Frage

Ich möchte eine Funktion ausführen, wenn dem HTML einige Divs oder Eingaben hinzugefügt werden.Ist das möglich?

Kommt beispielsweise eine Texteingabe hinzu, dann soll die Funktion aufgerufen werden.

War es hilfreich?

Lösung

Update 2015, neu MutationObserver wird von modernen Browsern unterstützt:

Chrome 18+, Firefox 14+, IE 11+, Safari 6+

Wenn Sie ältere unterstützen müssen, können Sie versuchen, auf andere Ansätze wie die hier genannten zurückzugreifen 5 (!) Jahre alte Antwort unten.Es gibt Drachen.Genießen :)


Jemand anderes ändert das Dokument?Denn wenn Sie die volle Kontrolle über die Änderungen haben, müssen Sie nur noch Ihre eigenen erstellen domChanged API – mit einer Funktion oder einem benutzerdefinierten Ereignis – und lösen/rufen Sie sie überall dort auf, wo Sie Dinge ändern.

Der DOM Level-2 hat Arten von Mutationsereignissen, aber ältere IE-Versionen unterstützen es nicht.Beachten Sie, dass es sich um Mutationsereignisse handelt in der DOM3-Events-Spezifikation veraltet und habe ein Leistungseinbußen.

Sie können versuchen, ein Mutationsereignis mit zu emulieren onpropertychange im IE (und auf den Brute-Force-Ansatz zurückgreifen, wenn keiner davon verfügbar ist).

Für ein voll domChange ein Intervall könnte übertrieben sein.Stellen Sie sich vor, Sie müssen den aktuellen Status des gesamten Dokuments speichern und prüfen, ob alle Eigenschaften jedes Elements gleich sind.

Wenn Sie nur an den Elementen und ihrer Reihenfolge interessiert sind (wie Sie in Ihrer Frage erwähnt haben), a getElementsByTagName("*") kann arbeiten.Dies wird automatisch ausgelöst, wenn Sie ein Element hinzufügen, entfernen, Elemente ersetzen oder die Struktur des Dokuments ändern.

Ich habe einen Proof of Concept geschrieben:

(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);

Verwendung:

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

Dies funktioniert auf IE 5.5+, FF 2+, Chrome, Safari 3+ und Opera 9.6+

Andere Tipps

Dies ist der ultimative Ansatz bisher mit kleinstem Code:

ie9 +, ff, webkit:

mit mutationobserver und zurück zum veralteten Mutation Events Bei Bedarf:
(Beispiel unten, wenn nur für DOM-Änderungen in Bezug auf angehängte oder entfernte Knoten)

generasacodicetagpre. generasacodicetagpre.

Ich habe kürzlich ein Plugin geschrieben, das genau das tut - jquery.initialize

Sie verwenden es auf die gleiche Weise wie .each Funktion

$(".some-element").initialize( function(){
    $(this).css("color", "blue"); 
});

Der Unterschied zu .each ist - in diesem Fall wird Ihr Selektor benötigt .some-element und warten Sie in Zukunft mit diesem Selektor auf neue Elemente. Wenn ein solches Element hinzugefügt wird, wird es ebenfalls initialisiert.

In unserem Fall ändert die Initialisierungsfunktion einfach die Elementfarbe in Blau.Wenn wir also ein neues Element hinzufügen (egal ob mit Ajax oder sogar F12-Inspektor oder so), wie zum Beispiel:

$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!

Das Plugin wird es sofort initiieren.Außerdem stellt das Plugin sicher, dass ein Element nur einmal initialisiert wird.Wenn Sie also ein Element hinzufügen, dann .detach() Wenn Sie es aus dem Körper entfernen und es dann erneut hinzufügen, wird es nicht erneut initialisiert.

$("<div/>").addClass('some-element').appendTo("body").detach()
    .appendTo(".some-container");
//initialized only once

Plugin basiert auf MutationObserver - Es funktioniert auf IE9 und 10 mit den im Detail aufgeführten Abhängigkeiten Readme-Seite.

oder Sie können einfach Ihr eigenes Ereignis erstellen , das überall ausgeführt wird

generasacodicetagpre.

Voller Beispiel http://jsfiddle.net/hbmaam/mq7nx/

Das folgende Beispiel wurde von Mozilla Hacks ' Blog post und verwendet Mutationobserver .

generasacodicetagpre.

Browser-Unterstützung: Chrome 18+, Firefox 14+, dh 11+, Safari 6 +

Verwenden Sie den mutationobserver Schnittstelle, wie in Gabriele Romano's Blog

chrom 18+, Firefox 14+, dh 11+, Safari 6 +

generasacodicetagpre.

Wie wäre es mit der Erweiterung eines Jquery dafür?

generasacodicetagpre.

jQuery 1.9+ hat dazu aufgebaut (ich habe nicht getestet gehört).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top