As site developers using jQuery, we often attach jQuery behaviours through an attach function that's registered with $(document).ready();. Typically, behaviours attach to content identified by jQuery selectors, e.g., id or class values. This works great for the initial DOM ready state. But how can we ensure that these same behaviours are also attached to content loaded via ajax?
Of course, if I'm using all my own behaviours I can simply hack them to apply to ajax-loaded content. But the question is, how can we structure all our behaviours in such a way that others can use them for both 'normal' and ajax-loaded content? There are two parts to this issue: _____ (a) Behaviours list: How can we know what behaviours need to be reattached? To reattach all behaviours to newly loaded and rendered content, we need to know what behaviours exist. (b) Avoiding duplication: How can we ensure that behaviours are attached only to newly loaded content? If we simply rerun the original attachment code, we may end up with multiple behaviour instances attached to individual elements that the behavours were already attached to. _____ A concrete example: in Drupal we have various jQuery behaviours that may be attached to content on page ready: autocomplete text fields, collapsing fieldsets, etc. These are registered through $(document).ready. If we ajax load and render new content, though, it doesn't get the behaviours and so is broken. If we manually call the functions that attach the behaviours, we get duplicate behaviours (e.g., two icons for collapsing fieldsets). Issue (b) seems relatively easy to address. One way is by filtering the jQuery selector by class name and then adding that class to all processed content: $('div.mybehavior:not(.mybehavior-processed)').each(function() { $(this) ... .addClass('mybehavior-processed'); }); Is this the best way? Issue (a) is more difficult. We can't rely on what was registered through $(document).ready() because the jQuery.readyList is emptied after being used. One possible approach would be to extend jQuery with array of behaviours. Here's a rough idea: jQuery.extend({ behaviors: [], registerBehavior: function(attachFunction) { jQuery.behaviors.push(attachFunction); jQuery.readyList.push(attachFunction); }); jQuery.each( attachBehaviors: function() { var elt = this; if ( jQuery.behaviors) { // Execute all of them jQuery.each( jQuery.behaviors, function(){ this.apply( elt ); }); } }); Then, for behaviours, we would register them with $.registerBehavior(mybehaviourAttach); and then call after ajax-loading content with $(elt).attachBehaviors(); Is this a good general approach? Are there better solutions? What are people currently doing to address this issue? Thanks, Nedjo Rogers _______________________________________________ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/