Andres Andres - 13 days ago 8
Javascript Question

smoothState.js conflicting with other plugins

I have managed to implement the smoothState.js plugin on my website and it works nicely, but my other very simple jQuery plugin will not work, wich starts with:

$(document).ready()


I need to refresh the page in order for it to work again.

I've read the smoothState documentation and it says I should wrap your plugin initializations in a function that we call on both $.fn.ready() and onAfter — but I'm farely new to programming, so I'm asking for your help.

How can I make my jQuery plugins work with smoothState?

Answer

You need to wrap scripts that are initiated with $(document).ready() in a function, and then call that function when you need it.

For example, let’s say this is your current script:

$(document).ready(function() {
  $('.btn--homepage').click(function(e) {
    e.preventDefault();
    var goTo = $(this).attr('href');

    $('#page').addClass('is-exiting');
    $(this).addClass('exit-btn');

    setTimeout(function() {
      window.location = goTo;
    }, 260);
  });
});

It’ll work fine when the page loads as it’s wrapped in $(document).ready(function()), but as the page won’t be reloading when using Smoothstate, we need a way to call the snippet both when the page originally loads and when smoothstate loads content. To do this we’ll turn the above snippet in to a function like this:

(function($) {
  $.fn.onPageLoad = function() {
    $('.btn--homepage').click(function(e) {
      e.preventDefault();
      var goTo = $(this).attr('href');

      $('#page').addClass('is-exiting');
      $(this).addClass('exit-btn');

      setTimeout(function() {
        window.location = goTo;
      }, 260);
    });
  };
}(jQuery));

As you can see, we’ve swapped $(document).ready(function()) with the function wrapper, everything else stays the same.

So now we’ve got a function all we need to do is call it when the page loads and in Smoothstate.

To call it when a page loads all we need to do is this:

$(document).ready(function() {
  $('body').onPageLoad();
});

And to trigger it in Smoothstate we need to call it in the InAfter callback like this:

onAfter: function($container) {
  $container.onPageLoad();
}

And here's an example Smoothstate script showing where to put the onAfter callback:

$(function() {
  var $page = $('#main');
  var options = {
    prefetch : true,
    pageCacheSize: 4,
    forms: 'form',
    scroll: false,
    onStart: {
      duration: 1200,
      render: function($container) {
        $container.addClass('is-exiting');
        smoothState.restartCSSAnimations();
      }
    },
    onReady: {
      duration: 0,
      render: function($container, $newContent) {
        $container.removeClass('is-exiting');
        $container.html($newContent);
        $('html, body').scrollTop(0);
      }
    },
    onAfter: function($container) {
      $container.onPageLoad();
    }
  };
  var smoothState = $('#main').smoothState(options).data('smoothState');
});

Happy to provide further assistance if needed.