我想执行一个函数时,一些div或输入被添加到html。 这可能吗?

例如,添加了一个文本输入,然后应该调用函数。


当前回答

8年后,这是我使用MutationObserver和RxJS的解决方案

observeDOMChange(document.querySelector('#dom-changes-here'))
  .subscribe(val => log('DOM-change detected'));

与其他方法的主要区别是在DOM更改时触发CustomEvent,并通过以下特性侦听事件的恢复以有效地执行用户逻辑;

撤消连续的DOM更改,以防止执行过多 在给定的时间后停止观看 在停止监视DOM更改后删除事件侦听器/订阅者 观察一个框架(比如Angular)中发生的DOM变化是很有用的

import { fromEvent, timer} from 'rxjs';
import { debounceTime, takeUntil, tap } from 'rxjs/operators';

function observeDOMChange(el, options={}) {
  options = Object.assign({debounce: 100, expires: 2000}, options);

  const observer = new MutationObserver(list =>  {
    el.dispatchEvent(new CustomEvent('dom-change', {detail: list}));
  });
  observer.observe(el, {attributes: false, childList: true, subtree: true });

  let pipeFn;
  if (options.expires) {
    setTimeout(_ => observer.disconnect(), options.expires);
    pipeFn = takeUntil(timer(options.expires));
  } else {
    pipeFn = tap(_ => _); 
  }

  return fromEvent(el, 'dom-change')
    .pipe(pipeFn, debounceTime(options.debounce));
}

在stackblitz演示。

其他回答

使用MutationObserver界面,如Gabriele Romanato的博客所示

找到了,Chrome 18+,火狐14+

// The node to be monitored
var target = $( "#content" )[0];

// Create an observer instance
var observer = new MutationObserver(function( mutations ) {
  mutations.forEach(function( mutation ) {
    var newNodes = mutation.addedNodes; // DOM NodeList
    if( newNodes !== null ) { // If there are new nodes added
        var $nodes = $( newNodes ); // jQuery set
        $nodes.each(function() {
            var $node = $( this );
            if( $node.hasClass( "message" ) ) {
                // do something
            }
        });
    }
  });    
});

// Configuration of the observer:
var config = { 
    attributes: true, 
    childList: true, 
    characterData: true 
};

// Pass in the target node, as well as the observer options
observer.observe(target, config);

// Later, you can stop observing
observer.disconnect();

或者你可以简单地创建你自己的事件,到处运行

 $("body").on("domChanged", function () {
                //dom is changed 
            });


 $(".button").click(function () {

          //do some change
          $("button").append("<span>i am the new change</span>");

          //fire event
          $("body").trigger("domChanged");

        });

完整的示例 http://jsfiddle.net/hbmaam/Mq7NX/

到目前为止,使用最小代码的终极方法:

(IE11+, FF, Webkit)

使用MutationObserver并退回到已弃用的 突变事件(如果需要的话): (下面的示例仅用于涉及追加或删除节点的DOM更改)

var observeDOM = (function(){ var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; return function( obj, callback ){ if( !obj || obj.nodeType !== 1 ) return; if( MutationObserver ){ // define a new observer var mutationObserver = new MutationObserver(callback) // have the observer observe for changes in children mutationObserver.observe( obj, { childList:true, subtree:true }) return mutationObserver } // browser support fallback else if( window.addEventListener ){ obj.addEventListener('DOMNodeInserted', callback, false) obj.addEventListener('DOMNodeRemoved', callback, false) } } })() //------------< DEMO BELOW >---------------- // add item var itemHTML = "<li><button>list item (click to delete)</button></li>", listElm = document.querySelector('ol'); document.querySelector('body > button').onclick = function(e){ listElm.insertAdjacentHTML("beforeend", itemHTML); } // delete item listElm.onclick = function(e){ if( e.target.nodeName == "BUTTON" ) e.target.parentNode.parentNode.removeChild(e.target.parentNode); } // Observe a specific DOM element: observeDOM( listElm, function(m){ var addedNodes = [], removedNodes = []; m.forEach(record => record.addedNodes.length & addedNodes.push(...record.addedNodes)) m.forEach(record => record.removedNodes.length & removedNodes.push(...record.removedNodes)) console.clear(); console.log('Added:', addedNodes, 'Removed:', removedNodes); }); // Insert 3 DOM nodes at once after 3 seconds setTimeout(function(){ listElm.removeChild(listElm.lastElementChild); listElm.insertAdjacentHTML("beforeend", Array(4).join(itemHTML)); }, 3000); <button>Add Item</button> <ol> <li><button>list item (click to delete)</button></li> <li><button>list item (click to delete)</button></li> <li><button>list item (click to delete)</button></li> <li><button>list item (click to delete)</button></li> <li><em>&hellip;More will be added after 3 seconds&hellip;</em></li> </ol>

8年后,这是我使用MutationObserver和RxJS的解决方案

observeDOMChange(document.querySelector('#dom-changes-here'))
  .subscribe(val => log('DOM-change detected'));

与其他方法的主要区别是在DOM更改时触发CustomEvent,并通过以下特性侦听事件的恢复以有效地执行用户逻辑;

撤消连续的DOM更改,以防止执行过多 在给定的时间后停止观看 在停止监视DOM更改后删除事件侦听器/订阅者 观察一个框架(比如Angular)中发生的DOM变化是很有用的

import { fromEvent, timer} from 'rxjs';
import { debounceTime, takeUntil, tap } from 'rxjs/operators';

function observeDOMChange(el, options={}) {
  options = Object.assign({debounce: 100, expires: 2000}, options);

  const observer = new MutationObserver(list =>  {
    el.dispatchEvent(new CustomEvent('dom-change', {detail: list}));
  });
  observer.observe(el, {attributes: false, childList: true, subtree: true });

  let pipeFn;
  if (options.expires) {
    setTimeout(_ => observer.disconnect(), options.expires);
    pipeFn = takeUntil(timer(options.expires));
  } else {
    pipeFn = tap(_ => _); 
  }

  return fromEvent(el, 'dom-change')
    .pipe(pipeFn, debounceTime(options.debounce));
}

在stackblitz演示。

使用TrackChanges来检测html更改。 链接:https://www.npmjs.com/package/track-changes-js

例子

 let button = document.querySelector('.button');

 trackChanges.addObserver('buttonObserver', () => button);
 
 trackChanges.addHandler('buttonObserver', buttonHandler);

 function buttonHandler(button) {
   console.log(`Button created: ${button}`);
 }