6

I'm looking for something like this:

var div = document.createElement('div');
div.id = 'proprioceptiveDiv';
$(div).on('appendedToDOM', function() {
  // ...
});

document.body.appendChild(div); // triggers above handler

Does this exist? I'm using jQuery and would rather not import a whole plugin or another library just for this ability, so I'm only interested in a short solution.

Mark Vayngrib
  • 974
  • 5
  • 14
  • possible duplicate of [on append() do something](http://stackoverflow.com/questions/7167085/on-append-do-something) – DGS Sep 09 '13 at 11:59
  • That doesn't look like a standard event. Are you trying to trigger a custom event or are you just trying to defer execution until the DIV is attached to the DOM? – JC Ford Sep 09 '13 at 12:02
  • 1
    @DGS the difference is that I want to bind a handler to this event for a specific element, and not catch every single 'append' event and cross-check it with my div. I've seen the suggested duplicate question, and the accepted answer there doesn't seem to help with this case. – Mark Vayngrib Sep 09 '13 at 12:03
  • @JC yea, I want a custom event to be triggered when this element is attached to the DOM – Mark Vayngrib Sep 09 '13 at 12:03
  • Maybe write a special method just for this DIV which fires the event and does the append such as `div.appendAndNotify = function() {}` and just call that when you're ready to append it? Might be inelegant, but it might get you what you want. – JC Ford Sep 09 '13 at 12:06
  • @JC this would of course work, but it would be a kind last resort. If this was a one time thing, I would just trigger a custom event myself when appending the div to the DOM, or some callback, etc. However, I'd rather have a generic solution that I can use on any given element. – Mark Vayngrib Sep 09 '13 at 12:11
  • @MarkVayngrib there is no such event (if you don't count mutation events and mutationObservers which neither works cross-browser) – John Dvorak Sep 09 '13 at 12:18
  • @JanDvorak seems you're right. If no one comes up with a cool hack, I'll accept undefined's answer – Mark Vayngrib Sep 09 '13 at 12:24
  • I did some more looking around and I think the answer is overriding the .append() method of jQuery and having it trigger your custom event. (That was the answer that got downvoted and deleted here). The only downside is possible performance impact but it's easy enough to try it and see if it's significant. – JC Ford Sep 09 '13 at 12:43

2 Answers2

2

You can use Mutation Events but the events have been marked as deprecated in the DOM Events specification, as the API's design is flawed.

The MutationEvent interface was introduced in DOM Level 2 Events, but has not yet been completely and interoperably implemented across user agents. In addition, there have been critiques that the interface, as designed, introduces a performance and implementation challenge. DOM4 provides a new mechanism using a MutationObserver interface which addresses the use cases that mutation events solve, but in a more performant manner. Thus, this specification describes mutation events for reference and completeness of legacy behavior, but deprecates the use of the MutationEvent interface.

One simple option is using .trigger() method:

var $div = $(div).on('appendedToDOM', function() {
  console.log('appended');
});

// ...

$div.appendTo('body').trigger('appendedToDOM');

You can also create a helper function that appends the element and triggers a custom event:

function append(elem, target, cEvent) {
   if (typeof target === 'undefined') var target = document.body;
   if (typeof cEvent === 'undefined') var cEvent = 'appendedToDOM';
   $(elem).appendTo(target).trigger(cEvent);
}

// Usage
append(element [, targetElement] [, customEvent]);
Ram
  • 143,282
  • 16
  • 168
  • 197
  • 1
    I would prefer something generic, and not write trigger('appendedToDom') every time – Mark Vayngrib Sep 09 '13 at 11:58
  • 1
    @MarkVayngrib there's no event that triggers for an element when it is added to the document – John Dvorak Sep 09 '13 at 12:04
  • @JanDvorak right, in that case is there a solution with a custom event? – Mark Vayngrib Sep 09 '13 at 12:05
  • 1
    I'll accept this answer if a better one doesn't come along soon. Ideally I would want a solution that doesn't require the use of a special append method, as that would require me to change all existing code to use it, not to mention scour the code for $().html() or places where el.innerHTML is set directly. – Mark Vayngrib Sep 09 '13 at 12:20
  • 2
    @MarkVayngrib if you're really desperate, make yourself browser-dependent and use mutation observers with a fallback to mutation events... or use the deprecated mutation events directly. If you do either... welcome to the world of browser dependency hell. – John Dvorak Sep 09 '13 at 12:37
2

@Undefined's answer gave me an idea. As Mutation Events are deprecated, this is not a great solution, but anyway:

$(document).bind("DOMNodeInserted", function(e) {
  $(e.target).trigger('appendedToDOM');
});
Mark Vayngrib
  • 974
  • 5
  • 14
  • nice one, but please note that `DOMNodeInserted` doesn't work correctly in IE9 (nor does `DOMSubtreeModified`' however). – John Dvorak Sep 10 '13 at 07:41