How can I bind events to the Squarespace AjaxLoader?

拥有回忆 提交于 2019-12-13 14:41:18

问题


I'm working on a Squarespace site at the moment, trying to figure out how I can bind a function to their AjaxLoader without much success.

Here is a demo site that uses this loader

In my console I can see all the XHR requests being triggered when switching between pages, and I've tried using the debug to capture event listeners.

I thought something bound to "readystatechange" would work, but it only triggers on the initial page load.

$(window).on("readystatechange", doStuff);

回答1:


I found a pretty nice solution using mutationObservers on the Squarespace Answers forum – thank you @octopus!

Copy and pasted from here

Hope this helps anyone else struggling.

 window.onload = function(){
   react();
   watch(react);
 };
 function react() {
   var id = document.body.getAttribute('id'),
       target = 'collection-5787c6b0cd0f6801e859286a';
   console.log(id);
   if (id === target) {
     // execute your code for this page
   }
 }
 function watch(callback) {
   MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
   var observer = new MutationObserver(function(mutations) {
     for (var index = 0; index < mutations.length; index++) {
       var mutation = mutations[index];
       if (mutation.type === 'attributes') { 
         callback();
       }
     }
   });
   observer.observe(document.body, {
     attributes: true,
     attributeFilter: ['id']
   });
 }



回答2:


The ajaxLoader.js is using the modular pattern and has encapsulated the httpRequest. I don't believe you can bind to it.

  (function(window, document){
    'use strict';

     var DEBUG = true;
     var httpRequest; // THE HTTP REQUEST USED FOR THE AJAX
     var ajaxFired = false;
     var currentEvent;
     var currentTarget;
     var indexNextAnim = true;
     ...

The httpRequest is set and used in the ajax function:

ajax: function (url) {

  httpRequest = new XMLHttpRequest();
  httpRequest.open('GET', url);
  httpRequest.timeout = this.TIMEOUT;
  httpRequest.onreadystatechange = this.handleRequest.bind(this, url);
  httpRequest.ontimeout = this.handleTimeout.bind(this, url);
  httpRequest.send(null);
},



回答3:


This is very easy to solve. Simply modify the AjaxLoader prototype to add an additional custom init function right along side of where Squarespace runs their own block init.

This assumes you've bound some sort of custom object that holds your init function(s). Sometimes to better to use some sort of custom event emitter for this, but that would be some additional dev. This seems much easier.

 window.onload = function() {
   this.AjaxLoader.prototype.initializeSqsBlocks = function () {
     window.SQS.Lifecycle.init();

     console.log( "Foo!" );
     window.CUSTOM.YourCustomInitFunction();
   }
 };

The end result is that when the ajaxloader fires, it will trigger the initializeSqsBlocks init as usual, which you've now hijacked to add your own additional init function. It's kind of a makeshift way of attaching an emitter to the ajaxloader without modifying it too much.



来源:https://stackoverflow.com/questions/39409881/how-can-i-bind-events-to-the-squarespace-ajaxloader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!