is there a way to be notified when a function is registered via the jQuery $(document)ready() functionality and get a reference to that?
The background:
Im using a parent theme on a wordpress site, which uses ajax page transitions and document ready is only called on the first load. Now i want a reference to each function previously registered to call them again if my page changes.
The goal: is to restore the functionality of $(document).ready() as not only me, but many other plugins out there are using it and i obviously dont want to rewrite them all.
Yes, i could call MY registered function with no efford but this feels kind of lackluster while destroying the underlying functionality. By the way: it is the parent themes transitions, so overriding this wouldn't be the best solution either.
What i want is to provide an addition, that intercepts every registration and calls the registered functions again manually after the transition. Is that a good idea?
(notice calling ready() manually doesn't work if it was called already automatically on the initial page load)
why dont you wrap them all in a onPageChanged function and call that on document ready, and in the success handler from ajax calls
Related
What is the best way to use ready and ajaxStop together in jQuery? Currently I am using:
jQuery(document).ready(function($) {
$(document).bind('ready ajaxStop', function() {
$('[rel=tooltip], [data-toggle="tooltip"]').tooltip({
html: true
});
});
});
To me it seems redundant to use ready inside ready. It was the only think I could think of without duplicating code. Is there another event I should be calling with ajaxStop instead of ready? Or is there a better way to initialize my tooltip, along with a few other plugins and custom JS, which needs to be loaded on ready as well as when my page is reloaded via Ajax.
You can also solve this by firing a custom event every time page is reloaded with ajax or otherwise when the page content changes.
Also you don't need to handle ready again. Abstract the tooltip initialization code in another function, call the function directly or trigger the custom event.
I was wondering if there are any repercussions I can expect when changing from
$(document).ready(function() {...})
to
window.onload = function() {...}
The reason being I am making a widget and do not want to enforce a jQuery include in case the user already has it included in their app, nor do I want them to have to modify the widget code -- so I am dynamically determining if I should include it.
However, in order to dynamically include it, I do not have access to jQuery before the window.onload, which brings me to my scepticism.
My main worry is that this will disrupt the functionality of the user's app. So... will it?
Thanks in advance.
Your function will actually fire in a different point in the page lifecycle. onload is called early in the lifecycle before all the page elements are necesarily loaded, whereas the ready event fires later. If you want to attach to the event without using jQuery, you can easily do that too:
document.addEventListener('DOMContentReady', function()
{
// Stuff
});
I am using jQuery to make AJAX submits and receive JSON replies containing multiple DOM IDs and corresponding HTML fragments that I need to update. Thus, I do multiple jQuery.html calls like $('#id1').html('...'); $('#id2').html('...');.
For every fragment containing a ready handler like $(function(){...});, the event is immediately triggered. I'd prefer to call it once after all updates were made.
Is there any way to do that?
From what I've read so far, a jQuery.trigger() could be used to manually trigger the ready event. But I'd need to save and restore the current handlers or postpone event delivery by overwriting the jQuery internals somehow. The latter is something that I'd like to avoid, maybe there's some best practice I don't know yet?
Have a look at the holdReady function.
See: http://api.jquery.com/jQuery.holdReady/
I would start by moving the js you have in your views into external js files where they can be invoked from the ajax callback functions.
As you are finding out in-page ready events can soon leave you feeling out of control and become very hard to maintain. Regain control, namespace your js up into logical sections and lose the ready reliance.
There is no need for ready statements if you include your js before the closing body tag. The best advice I can give is to start being explicit in your apps lifecycle about what js gets called when, rather than relying on the well over abused ready statement.
Rebecca Murphy has written some very good articles/presentations about this.
I am using cody sherman's javascript code here: http://codysherman.com/tools/infinite-scrolling/code
I am also using a simple jquery script to dynamically change the background-images of the divs that hold the tumblr posts.
The jquery code works fine but I need a way to call the function again when the infinite scrolling script updates with new posts. A way of them talking to each other I guess.
You can see the page here: http://hypergeography.tumblr.com/
(It isn't using the infinite scrolling yet. but it does have the script that changes the background images.)
Any help would be appreciated.
If you feel safe enough, you could definitely get into that code (it's not long at all) and add some logic to the onreadystatechange section. This event is fired once the Ajax call is complete. If you hook into it, you could easily add something to talk to your code.
Another way is to hijack XMLHttpRequest, so that once its send() method is called, you attach your own event listener that monitors that request for the 'load' event. Once the request is done, you can call your custom functions. This could be done like this:
XMLHttpRequest.prototype.originalSend=XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send=function(s){
this.addEventListener('load',function(){
//CALL YOUR CODE HERE
},false);
this.originalSend(s);
}
Or instead, you could hijack the onreadystatechange function to add some of your own logic:
XMLHttpRequest.prototype.originalSend=XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send=function(s){
if(this.onreadystatechange){
var oldORSC=this.onreadystatechange;
}
this.onreadystatechange=function(){
if (this.readyState==4 && this.status==200){ //a successful request
//CALL YOUR CODE HERE
}
if(oldORSC){
oldORSC();
}
}
this.originalSend(s);
}
Of course, if you wanted to support IE, you would have to do similar things withe the ActiveXObject that they use for AJAX. But I don't use it so I can't give you any examples.
EDIT: this assumes your page is making calls only for this purpose. If you have other AJAX calls, you will need to add logic to determine which call is being used. For this, you could hook into the open() method and inspect the URL or parameters or whatever specific information will help you determine where the call is going, and then modify the request accordingly.
ALSO: make sure that these hijacks are called FIRST, before any of the other javascript.
I am trying to load the Zopim chat client. Normally it is included with a document write action. This causes it to be loaded before the domReady function is triggered, as it needs this to start itself.
I want to load it later, and this works by using prototype (framework determined by Magento) to create a new script element and attaching it to the head. The script is loaded perfectly, but the domReady doesn't fire, so the script is never started.
The script is a nameless class, by this I mean that all its functions are encapsulated in {}
UPDATE: Sorry, I got it wrong, it is as self invoking function, the same syntax as the first answer suggest.
(function C(){
})();
This function call when run sets up listening events for the domReady event under various browsers and then waits. When the domready event fires, it calls a function (that is within the self-invoked function) that starts everything. What I need, is a way to access this function somehow.
END UPDATE
Within that is a function named C.
How can I call this function directly?
Or put another way, how can I start an external javascript file that depends on domready going off, when that event doesn't happen?
Can I load an external javascript file into a variable, so I can name the class?
Can I access the nameless class {} somehow maybe via the script tag?
Is there a way to alter the external file/javascript so I can have it look for another event, one that I can trigger?
About the only solution I can think of at the moment is to create a iframe and load the script in that.
If you want to fire it after loading it asynchronously after the domready is already fired, you can do this:
Make your function C a self invoking function by:
(function C(){
})();
With this approach you would be changing the external script though.
You may trigger the event programmatically, for example:
window.dispatchEvent(new Event('DOMContentLoaded'));
See Creating and triggering events.
But note that this solution can be tricky to make it work correctly, cause when you trigger the event, some event handlers that have registered to the event will trigger a second time. And this causes problems like page not working as expected or an infinite loop (event registering, handler call, event registering, handler call indefinitely).
So you would need a solution to make sure that the different scripts that registered to the DOMContentLoaded event have their handlers only called 1 time exactly.