问题
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