2013-03-22 17 views
41

Mi chiedo come aggiungere un'altra chiamata di metodo all'evento window.onload una volta che è già stata assegnata una chiamata al metodo a .aggiungendo all'evento window.onload?

qualche Supponiamo che nello script ho questo incarico ...

window.onload = function(){ some_methods_1() }; 

e poi in seguito nello script ho questo incarico

window.onload = function(){ some_methods_2() }; 

Così com'è, si chiamerà solo some_methods_2 . C'è un modo per aggiungere alla precedente callback senza annullare some_methods_1? (e anche senza includere sia some_methods_1() e some_methods_2() nello stesso blocco funzione).

Immagino che questa domanda non riguardi veramente window.onload ma una domanda su javascript in generale. NON voglio assegnare qualcosa a window.onload in modo tale che se un altro sviluppatore dovesse lavorare sullo script e aggiungere un pezzo di codice che usi anche (senza guardare il mio codice precedente), disabiliterebbe il mio evento onload .

sto anche chiedendo la stessa cosa di

$(document).ready() 

in jQuery. Come posso aggiungere ad esso senza distruggere quello che è venuto prima, o che cosa potrebbe venire dopo?

+1

'$ (document) .ready()' accumularsi. Usalo se jQuery è a portata di mano. –

risposta

28

Se si utilizza jQuery, non è necessario fare nulla di speciale. Gestori aggiunti tramite $(document).ready() non sovrascrivono a vicenda, ma piuttosto eseguono a turno:

$(document).ready(func1) 
... 
$(document).ready(func2) 

Se non si utilizza jQuery, è possibile utilizzare addEventListener, come dimostrato da Karaxuna, più attachEvent per IE 9 < .

Si noti che onload non è equivalente a $(document).ready() - il primo attende CSS, immagini ..., mentre il secondo attende solo l'albero DOM. I browser moderni (e IE da IE9) supportano l'evento DOMContentLoaded nel documento, che corrisponde all'evento jQuery ready, ma IE < 9 non lo fa.

if(window.addEventListener){ 
    window.addEventListener('load', func1) 
}else{ 
    window.attachEvent('onload', func1) 
} 
... 
if(window.addEventListener){ 
    window.addEventListener('load', func2) 
}else{ 
    window.attachEvent('onload', func2) 
} 

Se nessuna opzione è disponibile (per esempio, non ha a che fare con i nodi DOM), è ancora possibile fare questo (sto usando onload come esempio, ma altre opzioni sono disponibile per onload):

var oldOnload1=window.onload; 
window.onload=function(){ 
    oldOnload1 && oldOnload1(); 
    func1(); 
} 
... 
var oldOnload2=window.onload; 
window.onload=function(){ 
    oldOnload2 && oldOnload2(); 
    func2(); 
} 

o, per evitare di inquinare il namespace globale (e probabilmente incontrare collisioni namespace), utilizzando il modello IIFE import/export:

window.onload=(function(oldLoad){ 
    return function(){ 
    oldLoad && oldLoad(); 
    func1(); 
    } 
})(window.onload) 
... 
window.onload=(function(oldLoad){ 
    return function(){ 
    oldLoad && oldLoad(); 
    func2(); 
    } 
})(window.onload) 
+1

Intendi "document.attachEvent ('onload' ...)", non "carica". ;) –

+0

@JamesWilkins hai ragione. Risolto, grazie –

+0

Non si dovrebbe usare document.addEventListener ("load") (non funziona sulla mia versione di firefox) ma invece window.addEventListener ("load"). Vedi http://stackoverflow.com/q/16404380/94102 –

42

È possibile utilizzare attachEvent (IE8) e addEventListener invece

addEvent(window, 'load', function(){ some_methods_1() }); 
addEvent(window, 'load', function(){ some_methods_2() }); 

function addEvent(element, eventName, fn) { 
    if (element.addEventListener) 
     element.addEventListener(eventName, fn, false); 
    else if (element.attachEvent) 
     element.attachEvent('on' + eventName, fn); 
} 
+0

quindi, per renderlo compatibile con più browser, dovrei usare entrambi? Inoltre, se più avanti nello script aggiungo una richiamata a window.onload dopo aver usato in precedenza addEventListener, viene annullato qualsiasi cosa che ho assegnato con addEventListener? – pepper

+3

@pepper risposta aggiornata. No, non sarà cancellato – karaxuna

6

Ci sono fondamentalmente due modi

  1. negozio il valore precedente window.onload modo che il codice può chiamare un gestore precedente, se presenti prima o dopo l'esecuzione del codice

  2. utilizzando l'approccio addEventListener (che, ovviamente, a Microsoft non piace e richiede l'utilizzo di un altro nome diverso).

Il secondo metodo vi darà un po 'più di sicurezza, se un altro script vuole usare window.onload e lo fa senza pensare alla cooperazione ma il presupposto principale per Javascript è che tutti gli script coopereranno come si sta cercando di fare .

Si noti che uno script errato che non è progettato per funzionare con altri script sconosciuti sarà sempre in grado di rompere una pagina, ad esempio facendo scherzi con i prototipi, contaminando lo spazio dei nomi globale o danneggiando la dom.

+0

questo è fantastico! per quanto riguarda jquery $ (documento) .ready() o bind()? – pepper

+0

Ti rendi conto che jQuery è solo Javascript, vero? Non ho controllato, ma suppongo che probabilmente utilizzi (2) se disponibile o (1) per i browser più vecchi. – 6502

+0

certo, stavo solo chiedendo perché $ (document) .ready() è un po 'diverso da window.onload ... "L'evento ready si verifica dopo che il documento HTML è stato caricato, mentre l'evento onload si verifica dopo, quando anche tutto il contenuto (ad esempio le immagini) è stato caricato. " – pepper

1

questo potrebbe non essere una scelta popolare, ma a volte gli script finiscono per essere distribuito in vari pezzi, in questo caso ho trovato questo per essere una soluzione rapida

if(window.onload != null){var f1 = window.onload;} 
window.onload=function(){ 
    //do something 

    if(f1!=null){f1();} 
} 

poi da qualche altra parte. ..

if(window.onload != null){var f2 = window.onload;} 
window.onload=function(){ 
    //do something else 

    if(f2!=null){f2();} 
} 

questo aggiornerà la funzione onload e la catena come necessari