2012-03-19 14 views
7

Mi piace eseguire script personalizzati su pagine che non possiedo o controllo. Molte volte queste pagine hanno creato contenuti dinamici a cui vorrei applicare una funzione.Gestore per nodi DOM creati dinamicamente man mano che vengono inseriti

È possibile? Se è così, come posso fare questo? Idealmente sto cercando qualcosa di live jQuery's live metodo, tranne che invece di vincolare un evento come click sarebbe più come un evento che accade quando l'elemento viene caricato nel DOM. L'evento load funzionerebbe per alcuni elementi ma non penso per tutto ...

Per questa domanda, si supponga di non poter guardare o modificare il codice che sta inserendo i nodi DOM. Mi piacerebbe una tecnica che potrei usare in un userscript o bookmarklet che potrebbe essere utilizzato su più siti non collegati.

Edit: Cerco qualcosa da usare sul mio Inverti colori bookmarklet: JavaScript: Invert color on all elements of a page

+0

Che tipo di funzione stai cercando di applicare? È possibile ascoltare l'evento 'DOMNodeInsertedIntoDocument', ma è probabile che si applichi a molti nodi inseriti che non saranno interessati. – nrabinowitz

+0

Sono interessato a ogni nodo in realtà. Sto cambiando i colori di tutto sulla pagina. – Muhd

risposta

6

Supponendo che si sta eseguendo un browser come Firefox o Chrome, è possibile ascoltare l'evento DOMNodeInserted:

$(document).on('DOMNodeInserted', function(e) { 
    $(e.target).css({ color : '#c00' }); 
}); 

$('body').append('<div>test</div>');​ 

Fiddle: http://jsfiddle.net/VeF6g/ (probabilmente non riesce a IE)

+1

Vorrei solo notare per motivi di lettori casuali: non usare gli eventi di mutazione se puoi evitarlo. Dettagli: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html – Nickolay

+1

@Nickolay - grazie per il riferimento. So che è una cattiva idea in generale utilizzarli, ma sembra ragionevole per il caso d'uso dell'OP (tra le altre cose, la discussione riguarda uno script utente, quindi sarà l'unico a essere colpito da lentezza o arresti anomali). – nrabinowitz

1

Questo è piuttosto difficile da realizzare, perché non esiste un evento vitale per reagire a DOM cambia. Preferirei invece attenermi alla delega degli eventi.

Ma ci sono alcuni eventi che potresti trovare utili o interessanti. Su Mozilla Developer Network's list of DOM events si può vedere ad esempio .:

  • DOMNodeInserted,
  • DOMNodeInsertedIntoDocument,
  • DOMNodeRemoved,
  • DOMElementNameChanged,

Tutti loro però sono contrassegnati come bozze W3C.

+0

Quali browser sono stati implementati? Idealmente mi piacerebbe qualcosa che funzioni in Chrome. – Muhd

+0

Il contrassegno 'bozza' è una svista su parte degli editor MDC. Questi eventi erano anche negli eventi DOML2, che è "raccomandazione". Il fatto è che la maggior parte di questi eventi funziona su tutto tranne IE; ma dovresti evitare di usarli, se puoi, dato che hanno grossi inconvenienti (dettagli: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) – Nickolay

1

Un modo generico per rilevare l'inserimento del nodo consiste nell'utilizzare l'evento di mutazione DOMNodeInserted.

Sono interessato a ogni nodo in realtà. Sto cambiando i colori di tutto sulla pagina.

A tale scopo, una soluzione migliore è iniettare un foglio di stile dinamico, sufficiente con il flag !important. Se si desidera solo cambiare i colori, si consiglia l'estensione Stylish (Stylish for Chrome) anziché GreaseMonkey.

+0

Giusto, ma il '! la bandiera "importante" distruggerebbe molte pagine. Sto cercando di creare uno script intelligente che funzioni su molte pagine diverse e che abbia un bell'aspetto. – Muhd

+0

@Muhd È possibile scegliere selettori intelligenti per selezionare solo elementi specifici. Elegante supporta la selezione del dominio usando RegExes tramite '@ -moz-document regexp()' - Vedere anche ['@ document'] (https://developer.mozilla.org/en/CSS/@document). –

1

Se non si dispone di l'accesso a una libreria come jQuery, qui è la sintassi in solo- JavaScript:

document.addEventListener('DOMNodeInserted', nodeInsert) 

function nodeInsert() { 
    event.srcElement.style.color = '#ffffff' 
} 

Penso che dovrebbe funzionare nella maggior parte dei browser.

3

Ecco un buon modo per gestire l'evento di inserimento del nodo. imposta le animazioni per l'elemento che stai per aggiungere usando css.

<style type="text/css"> 

/* set up the keyframes; remember to create prefixed keyframes too! */ 

@keyframes nodeInserted { 
from { opacity: 0.99; } 
to { opacity: 1; } 
} 

#parent > button { 
animation-duration: 0.001s; 
animation-name: nodeInserted; 
} 

</style> 

#parent è l'id del div, in cui ho intenzione di aggiungere il pulsante di in modo dinamico.

<script type="text/javascript"> 

    var insertListener = function(event){ 
     if (event.animationName == "nodeInserted") { 
      // This is the debug for knowing our listener worked! 
      // event.target is the new node! 
      console.warn("Another node has been inserted! ", event, event.target); 
     } 
    } 

    document.addEventListener("animationstart", insertListener, false); // standard + firefox 
    document.addEventListener("MSAnimationStart", insertListener, false); // IE 
    document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari 

    setInterval(function(){ 

     var btn = document.createElement("BUTTON"); 

     var t = document.createTextNode("CLICK ME");  // Create a text node 

     btn.appendChild(t);   

     document.getElementById("parent").appendChild(btn); 

    }, 2000); 

</script> 
+0

Ho implementato questo metodo e programmato un ridimensionamento sensibile di un iframe all'interno del metodo 'insertListener'. La cosa strana è che il comportamento di ridimensionamento personalizzato si verifica solo dopo aver fatto scorrere verso il basso l'iframe, non prima. Qualche idea su cosa potrebbe succedere qui? –