如何正确实现自定义ajax ?

时间:2022-09-02 11:29:29

In order to keep the logotext <div class="small-7 medium-4 columns logo"> and the menu <nav class="pagedMenu" role="navigation">,without clipping on page refresh or while the content is loading from a page to another, I am trying to implement this solution made by @Buzinas (special thanks). In a few more words:

为了保持logotext

In header.php we have this script:

在头。我们有这个脚本:

<head>
    ...

    <script>
    function ajax(url, callback, method, params) {
      if (!method) method = 'GET';

      var xhr = new XMLHttpRequest();
      xhr.open(method, url);

      if (callback) xhr.addEventListener('load', function() {
        callback.call(this, xhr);
      });

      if (params) {
        params = Object.keys(params).map(function(key) {
          return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
        }).join('&');
        xhr.send(params);
      } else {
        xhr.send();
      }
    }

    // CUSTOM AJAX CONTENT LOADING FUNCTION
    function ajaxRevslider(obj) {

        // obj.type : Post Type
        // obj.id : ID of Content to Load
        // obj.aspectratio : The Aspect Ratio of the Container / Media
        // obj.selector : The Container Selector where the Content of Ajax will be injected. It is done via the Essential Grid on Return of Content

        var content = "";

        data = {};

        data.action = 'revslider_ajax_call_front';
        data.client_action = 'get_slider_html';
        data.token = '<?php echo wp_create_nonce("RevSlider_Front"); ?>';
        data.type = obj.type;
        data.id = obj.id;
        data.aspectratio = obj.aspectratio;

        // SYNC AJAX REQUEST
        jQuery.ajax({
            type:"post",
            url:"<?php echo admin_url('admin-ajax.php'); ?>",
            dataType: 'json',
            data:data,
            async:false,
            success: function(ret, textStatus, XMLHttpRequest) {
                if(ret.success == true)
                    content = ret.data;                             
            },
            error: function(e) {
                console.log(e);
            }
        });

         // FIRST RETURN THE CONTENT WHEN IT IS LOADED !!
         return content;                         
    };

    // CUSTOM AJAX FUNCTION TO REMOVE THE SLIDER
    function ajaxRemoveRevslider(obj) {
        return jQuery(obj.selector+" .rev_slider").revkill();
    }

    document.addEventListener('DOMContentLoaded', function() {
      var main = document.querySelector('div[role=main]'),
        spinner = document.querySelector('div.sk-spinner'),
        pages = {};

      window.addEventListener('load', function() {
          toggleSpinner(false);
      });

      function toggleSpinner(b) {       
        spinner.classList[b ? 'remove' : 'add']('hidden');
        document.getElementById('wrapper').style.opacity = b ? 0 : 1;
      }

      function changePage(url, title) {
        setTimeout(function() {
          window.SITE.init();
          window.vc_js();
        }, 0);

        history.pushState({
          html: main.innerHTML,
          title: title
        }, '', url);

        toggleSpinner(false);
      }

      document.getElementById('menu-menu-2').addEventListener('click', function(e) {
        var el = e.target;

        if (el.tagName === 'A') {
          e.preventDefault();
          toggleSpinner(true);

          if (pages[el.href]) {
            main.innerHTML = '';
            main.appendChild(pages[el.href]);
            changePage(el.href);
          }
          else {
            ajax(el.href, function(xhr) {
              var frag = document.createRange().createContextualFragment(xhr.responseText);
              main.innerHTML = '<div>' + frag.querySelector('div[role=main]').innerHTML + '</div>';
              //pages[el.href] = main.firstElementChild;

              var _currentScripts = [].slice.call(document.querySelectorAll('script'));

              [].forEach.call(frag.querySelectorAll('script'), function(el, i) {
                if ((el.src === '' && el.parentNode)
                    || el.src.indexOf('slider') >= 0
                    || el.src.indexOf('Scroll') >= 0
                    || el.src.indexOf('vendor') >= 0
                    || el.src.indexOf('composer') >= 0
                   ) {
                  var s = _currentScripts.filter(function(x) {
                    return x.src === el.src;
                  });

                  while (s.length) {
                    if (s[0].parentNode)
                      s[0].parentNode.removeChild(s[0]);
                    s.shift();
                  }

                  document.body.appendChild(el);
                }
              });

              [].forEach.call(frag.querySelectorAll('style'), function(el, i) {
                document.querySelector('head').appendChild(el);
              });

              changePage(el.href, frag.querySelector('title').textContent);
            });
          }
        }
      });

      window.addEventListener('popstate', function(e) {
        if (e.state) {
          main.innerHTML = e.state.html;
          document.title = e.state.title;
        }
      });
    });
    </script>

    ...
</head>

The following jquery-ready.js is registered/enqueued in script-calls.php:

下面的jquery ready。js在脚本调用中注册/进入队列。

(function($){
var readyList = [];

// Store a reference to the original ready method.
var originalReadyMethod = jQuery.fn.ready;

// Override jQuery.fn.ready
jQuery.fn.ready = function(){
    var args = [].slice.call(arguments);

    if(args.length && args.length > 0 && typeof args[0] === 'function') {
      readyList.push(args[0]);
    }

    // Execute the original method.
    originalReadyMethod.apply( this, args );
};

// Used to trigger all ready events
$.triggerReady = function() {
  $(readyList).each(function(i, el) {
      try {
          el.apply(el);
      } catch(e) {
          console.log(e);
      }
  });
};
})(jQuery);

Also, in page.php I replaced get_header() and get_footer() functions as follows:

另外,在页面。php I替换了get_header()和get_footer()函数如下:

<?php
if(!isset($_REQUEST['ajax'])){
    get_header(); 
}
?>
<?php 
    if (is_page()) {
        $id = $wp_query->get_queried_object_id();
        $sidebar = get_post_meta($id, 'sidebar_set', true);
        $sidebar_pos = get_post_meta($id, 'sidebar_position', true);
    }
?>
...

<?php
if(!isset($_REQUEST['ajax'])){
    get_footer();
}
?>

There are still some issues trying to load a page with Revolution slider or Visual Composer Parallax content, like we have on Parallax or About us pages for example.

仍然有一些问题试图加载一个带有旋转滑动条或视像编辑器视差内容的页面,就像我们在视差或关于我们的页面。

You can use this link and navigate to the above mentioned pages; Tests are made only in Chrome 45.0.2454.101 m 64-bit/ Win7, not yet prepared for IE, Firefox, mobile etc .

您可以使用此链接并导航到上述页面;测试只在Chrome 45.0.2454.101 m 64位/ Win7中进行,还没有为IE、火狐、移动等做好准备。

About the behaviour: Rev slider parallax content, will become scrambled from the second link visit (Home or Parallax pages); The Visual Composer parallax content (the guy at the desk picture, About us page for example) is fixed on the first link visit - after F5 will be fine;

关于行为:Rev滑动条视差内容,将从第二次链接访问中被打乱(首页或视差页面);视觉作曲人的视差内容(比如在桌子上的那个人,关于我们的页面)被固定在第一个链接访问上——在F5之后就可以了;

The menu mynewmenu.js will remember the state on session, so u'll have to close the browser in oder to visit multiple direct links properly.

菜单mynewmenu。js将记住会话的状态,因此您必须关闭oder中的浏览器才能正确访问多个直接链接。

I've received an answer from Rev slider support team telling me:

我收到了Rev滑块支持团队的回复,告诉我:

The best option for Ajax is to just add the slider's shortcode to a regular page/post, and then the slider's "init" script is will automatically be included with the slider's HTML. Then when the slider's HTML is removed from the DOM, all jQuery events are also removed. So all you really need to do is pull in the slider as page/post content, and then you won't need any custom script for the slider specifically.

Ajax的最佳选择是将滑块的短代码添加到常规的页面/post中,然后滑块的“init”脚本将自动包含在滑块的HTML中。然后,当从DOM中删除滑块的HTML时,也将删除所有jQuery事件。所以你真正需要做的就是把滑块作为页面/post内容拉进来,然后你就不需要任何专门为滑块定制的脚本了。

Unfortunately I have no idea how can I approach this, implementing the above sugestion into my already received solution.

不幸的是,我不知道如何实现这一点,在我已经接受的解决方案中实现上面的内容。

Could be something related to API(?) I've found these infos on Revolution slider / Visual Composer pages. Any thoughts?

可能与API有关(?)我在革命滑块/视觉作曲家页面上发现了这些信息。任何想法吗?

2 个解决方案

#1


2  

You should probably read:

你应该阅读:

You should pass PHP variables to your javascript files using wp_localize_script.

应该使用wp_localize_script将PHP变量传递给javascript文件。

Even if you don't do it that way, you shouldn't need to hack the main page templates just to serve specific content -- create a one-off page, then make a specific template for it. Then you can use that page's URL as your ajax endpoint.

即使你不这样做,你也不需要为了服务特定的内容而攻击主页模板——创建一个一次性的页面,然后为它创建一个特定的模板。然后,您可以使用该页面的URL作为您的ajax端点。

But if what you really need to do is run Rev Slider's shortcode (and the Parallax thing if it has one too) somewhere other than a page:

但是如果你真正需要做的是运行Rev Slider的简短代码(如果它也有的话,视差也有一个),而不是一个页面:

#2


0  

Do you need help with this still? I think the revolution slider's support team nailed it with the statements

你还需要帮助吗?我认为革命滑块的支持团队把它和声明联系在了一起

just add the slider's shortcode to a regular page/post

只需将滑块的短代码添加到常规页面/帖子中

and

all you really need to do is pull in the slider as page/post content

你真正需要做的是把滑动条作为页面/帖子内容。

So, use the slider on your WordPress page/post through the shortcode, [shortcode]. Then reference the $_GET[] and/or $_POST[] array elements in php (or javascript, however you're doing it) as needed.

所以,使用你的WordPress页面/文章上的滑块通过短代码,[短代码]。然后根据需要引用php(或javascript)中的$_GET[]和/或$_POST[]数组元素。

#1


2  

You should probably read:

你应该阅读:

You should pass PHP variables to your javascript files using wp_localize_script.

应该使用wp_localize_script将PHP变量传递给javascript文件。

Even if you don't do it that way, you shouldn't need to hack the main page templates just to serve specific content -- create a one-off page, then make a specific template for it. Then you can use that page's URL as your ajax endpoint.

即使你不这样做,你也不需要为了服务特定的内容而攻击主页模板——创建一个一次性的页面,然后为它创建一个特定的模板。然后,您可以使用该页面的URL作为您的ajax端点。

But if what you really need to do is run Rev Slider's shortcode (and the Parallax thing if it has one too) somewhere other than a page:

但是如果你真正需要做的是运行Rev Slider的简短代码(如果它也有的话,视差也有一个),而不是一个页面:

#2


0  

Do you need help with this still? I think the revolution slider's support team nailed it with the statements

你还需要帮助吗?我认为革命滑块的支持团队把它和声明联系在了一起

just add the slider's shortcode to a regular page/post

只需将滑块的短代码添加到常规页面/帖子中

and

all you really need to do is pull in the slider as page/post content

你真正需要做的是把滑动条作为页面/帖子内容。

So, use the slider on your WordPress page/post through the shortcode, [shortcode]. Then reference the $_GET[] and/or $_POST[] array elements in php (or javascript, however you're doing it) as needed.

所以,使用你的WordPress页面/文章上的滑块通过短代码,[短代码]。然后根据需要引用php(或javascript)中的$_GET[]和/或$_POST[]数组元素。