31

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:

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:

(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
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 .

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;

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.

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

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.

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
typo_
  • 11
  • 2
  • 15
  • 37
  • @Patel hey there, sorry for late reply; actually, the question I think that is pretty clear, perhaps, it's unclear taking in consideration the subject :) no offence. Are you a wordpress user/developer ? What I am trying to achieve is to have a fully functional ajax integrating Revolution slider and Visual Composer plugins in this thing; Anyway, I'll try to [apply this](http://stackoverflow.com/a/32928023/4642215) in a few, hope to have enough time; could be the right answer. Thank you for your interest. – typo_ Oct 20 '15 at 16:04
  • 2
    This would be easier to debug if you separate your concerns. JavaScript should not be in a PHP file. Use PHP file to render dynamic HTML and then use a JavaScript file to manipulate that. – freak3dot Oct 21 '15 at 20:32
  • @freak3dot hello there, I can do that, It's not a problem. I've moved the js sequence in _wp-content/themes/notio-wp/assets/js/buzinas.js_ file and also in this moment, the file is registered/enqueued in _script-calls.php_. – typo_ Oct 21 '15 at 20:50
  • @typo_78 please do not make your links hidden behind a shortener. There's no reason to do so as you gave it a caption and it only serves to make people fear it's malware. – Don Rhummy Oct 22 '15 at 00:18
  • @Don Rhummy, Thanks for your suggestion, I understand your point of view and I thought about that but if I don't make the links hidden, ggl will show at site name search all these stackoverflow pages—and I don't want that—am I right? – typo_ Oct 22 '15 at 07:35
  • @typo_78 Are you still on it? – Daniel Mizerski Feb 15 '16 at 06:07
  • @DanielMizerski sorry, not really at least not now... I'm pretty busy to continue this ajax thing :) – typo_ Feb 16 '16 at 00:13

2 Answers2

2

You should probably read:

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

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.

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:

drzaus
  • 24,171
  • 16
  • 142
  • 201
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.

Joshua K
  • 457
  • 3
  • 12
  • 1
    Thank you @JoshuaKersey for your feed-back, as soon as I have some free time I'll try ur solution; The problem is that the same behaviour we will have using the Visual Composer ... – typo_ Jan 17 '16 at 13:07