Reputation: 30434
Possible Duplicate:
DOM Mutation event in JQuery or vanilla Javascript
I am using backbone.js with dynamically generated templates and I am using several jQuery UI plugins, which attach to some classes, like slimScroll
:
$(function(){
$('.scroll').slimScroll({
height: $(window).height();
});
$('.stars').changeSelectBoxToRatingStars();
// ...
});
When I update the DOM tree (by rendering a template, loading new content, ...) and there are new elements added, these bindings need to be refreshed.
There are DOM Tree mutation events, which are now deprecated and not supported by IE (See DOM mutation events replacement). I have also seen .live()
in jQuery, which makes it possible to update .click()
an similar events, but it can't monitor the DOM for changes. Any suggestions for an efficient, standards-compliant way to monitor DOM tree changes in every browser?
Upvotes: 0
Views: 1658
Reputation: 51
JCADE (JQuery Create and Destroy Events) will do this. It uses behaviors for IE and DOM mutation events for other browsers. It does not use timing events and does not wrap JQuery methods like livequery.
https://github.com/snesin/jcade
$( document ).create( "a", function( event ) { alert( event.target ); });
Upvotes: 1
Reputation: 30434
I've finally managed to find a solution myself. As @Šime Vidas suggested in his comment, I am now handling the UI updates directly when needed. This is, when new stuff is rendered (in MainRouter#show
)
class MainRouter extends Backbone.Router
# [...]
show: (id) ->
item = Items.get(id)
# Render item
@view = new ShowView(model: item)
$(".content").html(@view.render().el)
# Update scrolling and UI items
window.updateUI()
and on when the window is resized:
window.$(window).resize -> window.updateUI()
The window.updateUI()
method itself does nothing fancy. It just adds slimScroll scrollbars where necessary and updates some divs, when the window is resized.
Thank you all for your help!
Upvotes: 0
Reputation: 140
I really do not recommend to use .live().
.live() associates the event to the highest DOM element (document, mainly). It's true that if you use it on some especific selector and then add some new element dynamically, this will also have the event previously associated, but every time you lauch that event, it'll have to go UP to the document element in the DOM tree to handle it.
Think about it in a huge DOM tree. You click on a td element and it runs all over the DOM up to the document element. It's pretty nasty.
The best way of dealing with this kind of situation is using .delegate(). It works similary to the .live() method, but doesn't lauches the event up to a handler in the document element, but in a upper element you choose.
Like this:
$(UpperElement).delegate(SelectorsOfClickableElements, eventsToDelegate, callbackFunction);
That way, when yoy click on that new element in the DOM, the handler of the event will be the upper element you choose, not the document element. Believe me, this is a lot faster that .live().
.on() works since jQuery 1.7. I'm a little dated about it but maybe you can find it better. Anyway, the .delegate() should work.
Sorry about my english.
Upvotes: 1