tags:

views:

175

answers:

1

I want to execute a function when some div or input are added to the html. Is this possible?

For example, a text input is added, then the function should be called.

+3  A: 

No there is no cross-browser way for that. The DOM Level-2 has Mutation event types, but you can't use it in production because of the lack of support in IE.

Someone else is changing the document? Because if you have full control over the changes you just need to create a domChanged simple callback and call it everywhere you modify things.

For a full domChange an interval would be an over-kill. Imagine that you need to store the current state of the whole document, and examine every element's every property to be the same.

Maybe if you're only interested in elements and their order (as you mentioned in your question), a getElementsByTagName("*") can work. This will fire automatically if you add an element, remove an element, replace elements or change the structure of the document.

UPDATE

You can try to emulate mutation event with onpropertychange in IE (and fall back to the brute-force approach if non of them is available).

I wrote a proof of concept:

//
//  ON DOCUMENT CHANGE
//  Makes it possible to execute code when the DOM changes.
//
//  Licensed under the terms of the MIT license.
//  (c) 2010 Balázs Galambosi
//

(function( window ) {

var last  = +new Date();
var delay = 100; // default delay

// Manage event queue
var stack = [];

function callback() {
  var now = +new Date();
  if ( now - last > delay ) {
    for ( var i = 0; i < stack.length; i++ ) {
       stack[i]();
    }
    last = now;
  }
}

// Public interface
var onDomChange = function( fn, newdelay ) {
  if ( newdelay ) 
    delay = newdelay;
  stack.push( fn );
};

// Naive approach for compatibility
function naive() {

  var last  = document.getElementsByTagName('*');
  var lastlen = last.length;
  var timer = setTimeout( function check() {

    // get current state of the document
    var current = document.getElementsByTagName('*');
    var len = current.length;

    // if the length is different
    // it's fairly obvious
    if ( len != lastlen ) {
      // just make sure the loop finishes early
      last = [];
    }

    // go check every element in order
    for ( var i = 0; i < len; i++ ) {
      if ( current[i] !== last[i] ) {
        callback();
        last = current;
        lastlen = len;
        break;
      }
    }

    // over, and over, and over again
    setTimeout( check, delay );

  }, delay );
}

//
//  Check for mutation events support
//

var support = {};

var el = document.documentElement;
var remain = 3;

// callback for the tests
function decide() {
  if ( support.DOMNodeInserted ) {
    window.addEventListener( "DOMContentLoaded", function() {
      if ( support.DOMSubtreeModified ) { // for FF 3+, Chrome
         el.addEventListener( 'DOMSubtreeModified', callback, false );
      } else { // for FF 2, Safari, Opera 9.6+
        el.addEventListener( 'DOMNodeInserted', callback, false );
        el.addEventListener( 'DOMNodeRemoved',  callback, false );
      }
    }, false );
  } else if ( document.onpropertychange ) { // for IE 5.5+
    document.onpropertychange = callback;
  } else { // fallback
    naive();
  }
}

// checks a particular event
function test( event ) {
  el.addEventListener( event, function fn() {
    support[event] = true;
    el.removeEventListener( event, fn, false );
    if( --remain === 0 ) decide();
  }, false);
}

// attach test events
if ( window.addEventListener ) {
  test( 'DOMSubtreeModified');
  test( 'DOMNodeInserted' );
  test( 'DOMNodeRemoved' );
} else {
  decide();
}

// do the dummy test
var dummy = document.createElement("div");
el.appendChild( dummy );
el.removeChild( dummy );

// expose
window.onDomChange = onDomChange;

})( window );

Usage

onDomChange(function(){ 
  alert("The Times They Are a-Changin'");
});

Works on: IE 5.5+, FF 2+, Chrome, Safari 3+, Opera 9.6+

galambalazs
cant we add a active listener(dont knw wht to say!) or something that check in interval and check the dom?
esafwan
see my update...
galambalazs
Got enough bold words in there? Jeesh!
Josh Stodola
thoughtful comment from you as always :) Have you learned to use the `this` keyword btw?
galambalazs