Amazing support - great products and code.

We have used a lot of extensions on the market place and have started to get a feel for who writes great ... Read more

Jul 10, 2015 DefianceSports

Certified Magento Enterprise developer Certified Magento developer Certified Magento theme developer Certified Magento specialist

Manadev is certified extension and theme
developer for Magento

How To Make Your Scripts Compatible With AJAX

AJAX Feature of SEO Layered Navigation Plus extension dynamically replaces parts of page HTML by removing HTML elements with old content and inserting elements with new content instead. Scripts attached to and working over removed elements stop working after old content is removed. Our extension does its best effort to attach same script to newly inserted HTML elements and indeed almost all dynamic behavior is working fine in newly inserted content.

Still in some cases manual effort is needed to make a script compatible with dynamic content replacement. This document discusses types of scripts, lists which kind of incomatibility is resolved automatically and provides practical guidance for maual resolution of incomatibilities which can't be manually resolved.

This document is highly technical. Magento JavaScript technical knowledge is expected.

Dynamic behavior on a page can be initialized and attached to HTML elements using several techniques:

  • By using Magento declarative notation in HTML markup
  • By initializing scripts imperatively either in DOMContentLoaded event handler (after all initial HTML is loaded) or directly in Javascript code (while loading/parsing/executing JavaScript tags or files).

Magento JavaScript initialization is described in detail here:

http://devdocs.magento.com/guides/v2.1/javascript-dev-guide/javascript/js_init.html

Scripts Initialized Via Magento Declarative Notation

With declarative notation scripts are initially attached to HTML elements with either of 2 following syntaxes:

  • via data-mage-init element attribute:

    <nav data-mage-init='{ "<component_name>": {...} }'></nav>
    
  • via <script> tags of text/x-magento-init type:

    <script type="text/x-magento-init">
    {
        // components initialized on the element defined by selector
        "<element_selector>": {
            "<js_component1>": ...,
            "<js_component2>": ...
        }
    }
    </script>    
    

After old content is deleted and new AJAX content is inserted into DOM, scripts bound to old HTML elements stop working and new instances of declaratively initialized scripts are created and attached to new content automatically.

In your script initialization code you can check if script is being initialized during initial page load or during AJAX refresh:

if ($(document).data('mana-replacing-content')) {
    // script is being reinitialized after AJAX refresh
}
else {
    // script is being initialized on initial page load
} 

Scripts Initialized Imperatively

By using imperative notation, scripts can be initialized anywhere in your code, for instance while handling DOMContentLoaded event:

$(function() {
    // in some place your script is initialized. Initialization may include 
    // attaching event handlers to HTML elements, making changes to HTML
    // elements, preparing initial component state
});  

After old content is deleted and new AJAX content is inserted into DOM, scripts bound to old HTML elements using imperative notation stop working and imperatively created scripts are not reinitialized and not attached to newly inserted content.

Reinitialization of such scripts should be done manually by handling mana-before-replacing-content and mana-after-content-replaced events.

Handling Script Shutdown and Reinitialization Events

In most cases creating and attaching new script instances to new content is enough and no customization is needed. However, you might want to have more precise control over stopping old script instances (attached to content being removed) and over creating new script instances (attached to newly inserted content).

mana-before-replacing-content Event

Before old content is removed, mana-before-replacing-content event is triggered. Handling this event can be handy:

  • state data of your script can be saved to some temporary storage so, that after new content is inserted, current script state can be restored into new instance of the script, the one bound to newly insterted HTML elements.
  • timers or any long-running processes can be shut down

You can handle mana-before-replacing-content event by using the following code snippet:

$(document).on('mana-before-replacing-content', function(event, $containers) {
    // save state data to temporary storage
    // shut down timers and release other resources 
});   

Event handler contains additional parameter $containers - jQuery selector object of all top level elements being replaced. You can use this parameter to find all elements your script is working with.

mana-after-content-replaced Event

Just after new content is inserted, mana-after-content-replaced event is triggered. Handling this event can be handy:

  • imperatively created scripts can be reinitialized
  • state data of your script can be restored from temporary storage to which is was saved in mana-before-replacing-content event handler.
  • timers or any long-running processes can be restarted

You can handle mana-before-replacing-content event by using the following code snippet:

$(document).on('mana-after-content-replaced', function(event, $containers) {
    // reinitialize imperatively created scripts
    // restore state data from temporary storage
    // restart timers and reallocate other resources 
});   

Event handler contains additional parameter $containers - jQuery selector object of all inserted top level elements. You can use this parameter to find all elements your script is working with.

We Accept: PayPal Visa MasterCard American Express Discover