0

I got to refactor big one-page application with complex UI.

There is following code in document.ready function

$('table.datatable').dataTable({ ... params ... });
$('div.tooltip').tooltip({ ... params ... });
$('ul.dropdownMenu').menu({ ... params ... });

As you can see in this code we search for different HTML controls and call to appropriate jQuery plugins that implement these controls' behavior.

However, since the page is very dynamic new datatables, tooltips and menus are added all the time and since JS functions were called at very beginning of application - those elements have no needed functionality unless I manually call appropriate plugin for them.

I'd like to eliminate the need to call jQuery plugin after each DOM change but don't know how to do it better.

One option is to fire an event each time I am adding anything to DOM and re-call this plugins in event's listener, however I don't like this solution because of need to remember fire the event each time.

I read about jQuery's on function which attach events also for not yet exists elements, but what event do I need? AFAIK there is no domchange event.

Any advises?

Boffin
  • 570
  • 2
  • 7
  • 21
  • possible duplicate of [How do you do something if the DOM is changed?](http://stackoverflow.com/questions/12102391/how-do-you-do-something-if-the-dom-is-changed) – Joseph Silber Jan 27 '13 at 17:39
  • 1
    There is no such event that you can use reliably. There are the [Mutation events](http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents) which are deprecated, and then there is the [Mutation observers](https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#mutation-observers) interface, which is work-in-progress. Both are not widely supported by modern browsers. – lanzz Jan 27 '13 at 17:42
  • There is an ancient jQuery plugin that does exactly that, but it does so via polling the selector. Either use Mutation Observers for FF+WK and mutation events for the rest, or just poll, or call an event manually. – John Dvorak Jan 27 '13 at 17:48

1 Answers1

1

Your only option is to hook up your plug-ins on new items after they are added to the DOM. The best cross browser option would be to hook into each place that adds these types of elements to the DOM and simply deal with the new items there by calling some additional function on them. What you need to look for is where you can easily hook into your existing code after new elements have been added to the DOM and then fix up those new elements at that point. Without knowing your code and where the DOM is modified, we can't really advise the best way to do that.

Generically monitoring the DOM for new items with a single method is not possible in a cross browser fashion. Mutation observers are the latest standard way to do this, but it is not supported in many browsers yet. Mutation events came before mutation observers, but is now deprecated.

jQuery's .on() will not do what you want here - it can be used to handle dynamically added DOM elements, but not in the way you want. Your plug-ins could have been designed to handle their events with use .on(), but unless they were designed that way and you can take advantage of that, there isn't a simple way for you to use it to get your desired behavior without rewriting a portion of the plugin.

jfriend00
  • 683,504
  • 96
  • 985
  • 979