Ich möchte eine Funktion ausführen, wenn ein div oder eine Eingabe zur html-Datei hinzugefügt wird. Ist dies möglich?
Wird zum Beispiel eine Texteingabe hinzugefügt, so sollte die Funktion aufgerufen werden.
Ich möchte eine Funktion ausführen, wenn ein div oder eine Eingabe zur html-Datei hinzugefügt wird. Ist dies möglich?
Wird zum Beispiel eine Texteingabe hinzugefügt, so sollte die Funktion aufgerufen werden.
(IE11+, FF, Webkit)
Verwendung von MutationObserver und den Rückgriff auf die veraltete Mutationsereignisse falls erforderlich:
(Beispiel unten, wenn nur für DOM-Änderungen in Bezug auf hinzugefügte oder entfernte Knoten)
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 foo 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>…More will be added after 3 seconds…</em></li>
</ol>
MutationObserver
wird von modernen Browsern unterstützt:Chrome 18+, Firefox 14+, IE 11+, Safari 6+
Wenn Sie ältere Menschen unterstützen müssen, können Sie auf andere Ansätze zurückgreifen, wie die in diesem Artikel genannten 5 (!) Jahre alte Antwort unten. Es lebe der Drache. Viel Spaß :)
Jemand anderes ändert das Dokument? Denn wenn Sie die volle Kontrolle über die Änderungen haben, müssen Sie nur Ihr eigenes Dokument erstellen. domChanged
API - mit einer Funktion oder einem benutzerdefinierten Ereignis - und lösen Sie sie überall dort aus, wo Sie Dinge ändern.
En DOM Level-2 hat Arten von Mutationsereignissen , aber ältere Versionen des IE unterstützen es nicht. Beachten Sie, dass die Mutationsereignisse veraltet in der DOM3 Events Spezifikation und haben eine Leistungseinbuße .
Sie können versuchen, das Mutationsereignis zu emulieren mit onpropertychange
in IE (und greifen auf den Brute-Force-Ansatz zurück, wenn keiner von ihnen verfügbar ist).
Für eine vollständig domChange ein Intervall könnte ein Overkill sein. Stellen Sie sich vor, Sie müssen den aktuellen Zustand des gesamten Dokuments speichern und die Eigenschaften jedes Elements überprüfen, damit sie gleich bleiben.
Wenn Sie nur an den Elementen und ihrer Reihenfolge interessiert sind (wie Sie in Ihrer Frage erwähnt haben), könnte eine getElementsByTagName("*")
funktionieren kann. Dies wird automatisch ausgelöst, wenn Sie ein Element hinzufügen, ein Element entfernen, Elemente ersetzen oder die Struktur des Dokuments ändern.
Ich habe eine Machbarkeitsstudie 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 mit IE 5.5+, FF 2+, Chrome, Safari 3+ und Opera 9.6+
Das folgende Beispiel wurde von Mozilla Hacks' angepasst Blogbeitrag und verwendet MutationObserver .
// Select the node that will be observed for mutations
var targetNode = document.getElementById('some-id');
// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true };
// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type == 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};
// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
// Later, you can stop observing
observer.disconnect();
Browser-Unterstützung: Chrome 18+, Firefox 14+, IE 11+, Safari 6+
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 - er nimmt Ihren Selektor, in diesem Fall .some-element
und warten auf neue Elemente mit diesem Selektor in der Zukunft, wenn ein solches Element hinzugefügt wird, wird es auch initialisiert werden.
In unserem Fall ändert die Initialisierungsfunktion einfach die Farbe des Elements in Blau. Also, wenn wir ein neues Element hinzufügen (egal, ob mit Ajax oder sogar F12 Inspektor oder etwas) wie:
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
Das Plugin wird es sofort starten. Außerdem sorgt das Plugin dafür, 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 dann wieder hinzufügen, wird es nicht erneut initialisiert.
$("<div/>").addClass('some-element').appendTo("body").detach()
.appendTo(".some-container");
//initialized only once
Das Plugin basiert auf MutationObserver
- es funktioniert mit IE9 und 10 mit den Abhängigkeiten, wie sie in der Liesmich-Seite .
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations, observer) {
// fired when a mutation occurs
console.log(mutations, observer);
// ...
});
// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
subtree: true,
attributes: true
//...
});
Vollständige Erklärungen: https://stackoverflow.com/a/11546242/6569224
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.