I connected several super plugs to the page:
$("*[data-foo]").foo(); $(".bar").bar(); $("pabi").baz(); But after downloading via AJAX, the code stops working! How to fix it?!
I connected several super plugs to the page:
$("*[data-foo]").foo(); $(".bar").bar(); $("pabi").baz(); But after downloading via AJAX, the code stops working! How to fix it?!
To say that "the code stops working" is incorrect. Because the code did not start working. When you write $(селектор).метод() - it means a single method call. This method is applied to all elements corresponding to the passed selector that were at that moment on the page .
It is usually said that in order to correct the error, after updating the page via ajax, you need to run the code again. But this is not always true.
Repeated call of the form $(".bar").bar(); will call the bar plugin not only on new elements - but also on old ones. At best, it will be useless time spent. But in the worst case, because of the repeated call, something will break (and if you subscribed to events, something will break, guaranteed!). Therefore it is necessary to apply plugins only to the updated container.
There are also rakes on how to call these plugins after an update. Usually they try to do this through an inline script in the server response - but in this case, this script does not have access to the updated item. It is necessary to search in the code where the update itself occurs - and edit there.
The above was a general principle. Below I will write a way to try to make the code work in a simple case.
We collect all the "improvements" pages in one place:
applyPlugins(); // ... function applyPlugins() { $("*[data-foo]").foo(); $(".bar").bar(); $("pabi").baz(); } We change the resulting function so that it acts only inside the container passed to it:
applyPlugins($(document)); function applyPlugins($cnt) { $cnt.find("*[data-foo]").foo(); $cnt.find(".bar").bar(); $cnt.find("pabi").baz(); } Here we used the find method, which looks for children.
Important! The applyPlugins function applyPlugins not access elements outside the $cnt container passed to it!
We find in the code those places where dynamic content update or element creation is performed.
This could be a .html(...) call:
$.ajax({ // ... success: function (data) { $("#some_block").html(data); } }); In this case, after the html call, add the applyPlugins call:
$.ajax({ // ... success: function (data) { applyPlugins($("#some_block").html(data)); } }); This could be a .load() call:
$("#some_block").load("http://some/url"); In this case, add a parameter with a callback function there:
$("#some_block").load("http://some/url", function () { applyPlugins($(this)); }); It may be something else. But I still hope that you will find this place - this is your code, and not someone else :)
The method above will not work if the selector used for the plugin passes through a dynamic container:
$(".foo .bar .baz").somePlugin(); $(".bar").load(...); In this case, an attempt to directly rewrite applyPlugins in the form of $cnt.find(".foo .bar .baz").somePlugin() will fail because neither .foo nor .bar is a child of the updated container.
In this case, you probably should take a closer look at what and how you update or download instead of blindly applying the trick to applyPlugins.
Or you can try to do something like this in order to foresee all cases - but this code for understanding and for debugging will be rather heavy:
$cnt.find(".foo .bar .baz").somePlugin(); $cnt.filter(".foo, .foo *").find(".bar .baz").somePlugin(); $cnt.filter(".foo .bar, .foo .bar *").find(".baz").somePlugin(); (Here it is checked whether the current container is a .foo element or its child element, and if it is, the first element is skipped on the .foo .bar .baz path. This code assumes that one .foo cannot be nested into another. The same for .bar .)
PS Although I only spoke about plugins, the answer can also be used to subscribe to events. But it will not be the best way - because there is a simpler way. Most of the events are pop-up - and therefore they can be caught in the root of the document. And jQuery has built-in mechanisms for filtering pop-up events. Example:
$(document).on("click", "a[data-href]", function (e) { // ... }) This handler will listen to clicks on any links with the data-href attribute set regardless of how and when they appeared on the page.
Source: https://ru.stackoverflow.com/questions/930996/
All Articles
just sayin'- SLy_huh