3

In my page I change one attribute of an element based on another attribute. Like this:

$("body").find("[data-action=new]").attr("data-original-title", "Create appointment");

Doing that, this element will display a tooltip with "Create appointment" text.

Like this I have any others.

The problem begin when I insert some elements via JS in my DOM.

There is any way to delegate this operation to avoid calling this every time I insert one element?

Update

I'm looking for a simple solution to setup my tooltips. The DOMObserver looks too heavy for use here. Or not?

Beetlejuice
  • 4,292
  • 10
  • 58
  • 84
  • The only things I can think of would be to setup a [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) and let that handle the inserting of the attributes, or create a custom event and trigger it on insert. Not sure if either of those is any better though. – Dave Jun 11 '15 at 16:52
  • Interesting related posts [here](http://stackoverflow.com/questions/7434685/event-when-element-added-to-page) and [here](http://stackoverflow.com/questions/1490313/how-to-do-an-action-when-an-element-is-added-to-a-page-using-jquery). Might provide some helpful ideas. – showdev Jun 11 '15 at 16:52
  • 1
    possible duplicate of [Most efficient method of detecting/monitoring DOM changes?](http://stackoverflow.com/questions/2457043/most-efficient-method-of-detecting-monitoring-dom-changes) – vinayakj Jun 11 '15 at 16:58
  • @vinayakj That post references a method now deprecated and removed from jQuery - probably not a duplicate in today's context. – Scott 'scm6079' Jun 11 '15 at 17:01
  • 2
    @Scott'scm6079' it also refers to plain javascript approach too not just jquery.. plenty of answers are available on that post.. – vinayakj Jun 11 '15 at 17:02
  • 1
    I looked through the post again, I still don't think that post answers this at all -- I've taken the time to writeup a solution that does answer the need. – Scott 'scm6079' Jun 11 '15 at 17:09
  • here @Scott'scm6079' , https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver was also from same post – vinayakj Jun 11 '15 at 17:59
  • @OP - Dom observer isn't heavy, since you only get the changed nodes - instead of having to travers the entire Dom. The whole idea of Dom observer is to keep things lighter than polling or other nasties. One other potential is how you are creating the dynamic objects. Can you just set the correct attib when you create the element? – Scott 'scm6079' Jun 11 '15 at 18:27

1 Answers1

1

A mutation observer seems appropriate, monitoring the addedNodes property:

var targetNodes         = $("body"); // best to make this more specific, e.g. .myNodes
var MutationObserver    = window.MutationObserver || window.WebKitMutationObserver;
var myObserver          = new MutationObserver (mutationHandler);
var obsConfig           = { childList: true, characterData: true, attributes: true, subtree: true };

targetNodes.each ( function () {
    myObserver.observe (this, obsConfig);
} );

function mutationHandler (mutationRecords) {
    mutationRecords.forEach ( function (mutation) {
        if (typeof mutation.addedNodes == "object") {
            var jq = $(mutation.addedNodes);
            jq.find("[data-action=new]").attr("data-original-title", "Create appointment");
        }
    } );
}
Scott 'scm6079'
  • 1,517
  • 13
  • 25
  • 2
    Yeah, but I expect you'll need a fallback for [IE < 11](http://caniuse.com/#feat=mutationobserver) – Dave Jun 11 '15 at 17:09
  • @dave Good point - this solution works in Chrome, Safari, IE11+. http://caniuse.com/#feat=mutationobserver – Scott 'scm6079' Jun 11 '15 at 17:10
  • Will this not cause a loop, because it will be changing the DOM again ? – Beetlejuice Jun 11 '15 at 17:28
  • In this case, they won't be added nodes - so it should be fine. However for people using this post for related items that's a great point. It would be easy to exclude changes by putting it in the inner find's selector. – Scott 'scm6079' Jun 11 '15 at 17:35