Instructions for dynamic websites

Below are the general rules for how to setup and code experiments on dynamic sites. The reason that these workarounds are needed is that a dynamic site does not reload the page when new content is loaded (on navigation etc). Because of this the changes that you made aren’t cleared on navigation (page load) and you have to handle this manually in your code instead to avoid unwanted duplicates of elements, functions etc. Please check our examples below on how to do this.

Setup Sitegainer for a dynamic site

To be able to use Sitegainer on a dynamic website you need to add a keyword in the javascript / jQuery tab. This is a comment that the Sitegainer script reads and adjusts to a dynamic website. Add this before your code (see image below).
/* sg_no_proxy */

Dynamic keyword


Change to correct Audience mode

You need to use the second mode (On load & URL change) or the third mode (Manual activation – sitegainer.newPage();)

  • On load & URL change – This might work if the url changes on navigation. Please control that this word correctly in preview, if not use the mode below.
  • Manual activation – sitegainer.newPage(); – This is a callback that you need to add to the code on your website and execute when new content is rendered. This is not added via Sitegainer. See link below for more information regarding the 3 modes.

Launch methods for dynamic pages

Audience mode

 

WYSIWYG-editor

You won’t be able to use this on a dynamic website. You need to make your changes manually.

 

Adding an element

  • You need to check if the element exist before you add it – if you don’t do this the element will be added again on navigation
  • This is easiest done by adding an if-statement that checks if the element exists.


Example: Adding a div with a menu icon in it.

Wrong way

$("header").append("<div class='sg-div-container'><i class='fa fa-bars'></i></div>");

Right way

if(JQSG(".sg-div-container").length < 1) {
    JQSG("header").append("<div class='sg-div-container'><i class='fa fa-bars'></i></div>");
}

 

CAUTION! If you add an element / make changes to an element that won’t re-render on navigation the added element will stay on the site even if the Audience becomes false upon navigation.

Example:

You make changes to the header that you don’t want on the checkout page and you have Audience set to be false in the checkout. These changes will still happen because the changes aren’t cleared on navigation. This is because the header does not re-render.

 

Adding/changing an element that does not exist on Document ready

If an element comes in after Document ready or if you use Sitetgainer's function to execute code before Document ready you need to check that the element(s) you want to change exist before you make your changes. The easiest way to do this is by setting an interval that checks if the element(s) exists and then clear the interval and do the changes. You can also use a Mutation Observer to act on changes in the DOM.

  • You need to check if the element exist before you add it - if you don’t do this the element will be added again on navigation
  • If the element doesn’t exist, add the elementet and clear the interval
  • If the element do exist, clear the interval

This is needed to avoid ticking intervals that aren’t cleared.


Example: Adding a div with a menu icon in it using a interval.

Wrong way

var sg_add_container_to_header_wrong = setInterval(function (){       
    if($("header").length > 0 && $(".sg-div-container-logo-wrong").length < 1) {
        clearInterval(sg_add_container_to_header_wrong);
        $("header").prepend("<div class='sg-div-container'><i class='fa fa-bars'></i></div>");
    }      
},100);

Right way - You need to clear the interval if the element already exist, otherwise you will have a ticking interval when you navigate

var sg_add_container_to_header = setInterval(function (){
    if($("header").length > 0 && $(".sg-div-container-logo").length < 1) {
        clearInterval(sg_add_container_to_header);
        $("header").prepend("<div class='sg-div-container'><i class='fa fa-bars'></i></div>");
    } else if($(".sg-div-container-logo").length > 0) {
        clearInterval(sg_add_container_to_header);
    }
},100);

 

Adding classes to elements that won't be re-rendered on navigation (body, header, etc)

If you for example add a class to body on click on some element to change another element at a certain state you need remove this class on load. Otherwise this class will still be there after navigation.

  • Remove the classes / IDs on load before you add them

 

Example:

Wrong way - this class will still be there after navigation even though you haven't clicked the menu because its added to body that isn't re-rendered.

$("body").on("click", ".sg-div-container-wrong", function(){
    $("body").addClass("clicked-element");
});

Right way - Always remove the class / ID before you add it

$("body").removeClass("clicked-element");

$("body").on("click", ".sg-div-container", function(){
    $("body").addClass("clicked-element");
});


Remove the event handler on your added functions.

Event handler functions that you add to elements that do not re-render will stay after navigation and will then be re-added (duplicated) if you don’t remove these first on load. This is easiest done with jQuerys off(); function.

Example: Menu toggles will show and hide in the same click because it will run the functions multiple times.

Wrong way

$("body").on("click", ".menu-toggle", function(){
    $("body").toggleClass("sg-show-menu");
});

Right way

$("body").off("click", ".menu-toggle");

$("body").on("click", ".menu-toggle", function(){
    $("body").toggleClass("sg-show-menu");
});