Always reapply the events to the DOM objects when they are inserted or loaded? NO MORE!
There are 3 solutions out there at the moment, jQuery listen, jQuery intercept both by event delegation addict Ariel Flesler and LiveQuery a plugin that reapplys all rules to every new DOM element loaded.
(Event delegation = every div.onclick will reach the parents of the div and can be captured there without binding directly to the div)
Listen and intercept both have a very limited selector choise, ‘a.b’ or ‘a#hello’. LiveQuery can be used rather thoughtfree but comes at a load-time-price for every existing/new element.
I like delegation more, but the selector choise is too limited. So here comes my
‘intercept any selector’ hack!
$.intercept(‘table td div.hello a#click :input’,’click’,fn) will bind your Event to the document, and run on every click of ‘table td…’. The lower you bind, the higher the performance cost(needless event checking)
$(‘table’).intercept(‘td div.hello a#click :input’,’click’,fn) will be faster…
As long as the DOM element you bound your events to is not replaced, all events will continue to work. This approach works best for few(and slow) rules that match many elements. There is no initial performance cost, so your page will load fast.
Only when a event is triggered the checking is done, and can be costly if you used a lot of events or a often triggered event (mouseover…).
The code you need to make it happen is here(insert into intercept.js):
...
for( selector in handlers ){
if( selector == 'self' && e.target == this || $.intercept.matches($target,selector))
ret = handlers[selector].apply(this, arguments) !== false && ret;
}
return ret;
};
/**
* Walk the element backwards and see if the selector matches (before reaching the document)
* @see https://pragmatig.wordpress.com/2008/03/08/event-delegation-with-almost-any-selector/
*/
$.intercept.matches = function(obj,selector){
var root_reached = false;
var words = selector.split(' ').reverse();
for(i in words){
do{
//match found?
if(obj.is(words[i])){
obj=$(obj.parent());
break;
}
obj=$(obj.parent());
root_reached = obj.get(0) == document;
}while(!root_reached);
if(root_reached)return false;
}
return !root_reached;
};