2013-05-15 16 views
6

di recente ho trovato la seguente domanda on-line:Come scrivere una funzione che aggiunge un elemento al DOM e ritarda il prossimo segno di spunta?

scrivere una funzione che prende un oggetto e lo aggiunge al DOM, rendendo in modo che gli eventi vengono memorizzati nel buffer fino a quando il segno di spunta accanto? Spiegare perché questo è utile?

Ecco la mia risposta:

function appendElement(element) { 
    setTimeout(function() { 
     document.body.appendChild(element); 
    }, 0); 
} 

Perché ho impostare l'intervallo a zero?

Secondo this article, impostare il timeout a 0, ritarda gli eventi fino al prossimo segno di spunta:

L'esecuzione di func va alla coda di eventi sul timer tick più vicino. Nota, non è immediatamente. Nessuna azione viene eseguita fino al prossimo segno di spunta.

Ecco quello che sono incerto:

  • è la mia soluzione giusta?
  • Non posso rispondere perché questo approccio è vantaggioso

Per avere un riferimento, ho ricevuto questa domanda da questo sito listing 8 JavaScript interview questions.

Vorrei anche precisare che sto facendo questa domanda per la mia ricerca e miglioramento e non come parte di una sfida di codice, domanda di intervista o compito a casa.

+0

Ciò consentirà di vedere ogni elemento aggiunto, uno alla volta (molto rapidamente ovviamente). Se lo metti in loop, il browser attenderà fino al termine prima di ridisegnare lo schermo. Questo è un esempio di sincronicità. – Ian

+0

Solo per chiarimenti, stai parlando della funzione chiamata all'interno di un ciclo, sì? Inoltre, un simile approccio causerebbe ripetizioni multiple, corretto? –

+0

Mi dispiace, non so perché ho pensato che questo codice venisse chiamato in un loop. Ho riletto solo ora. Credo che il mio punto fosse che se la tua funzione veniva chiamata in un ciclo (diciamo da 0 a 9), potresti/potresti vedere ogni elemento aggiunto, perché c'è un ridisegno poiché sono asincroni. Se non hai usato 'setTimeout' e hai appena chiamato' .appendChild' nello stesso ciclo 'for', li vedresti tutti visualizzati contemporaneamente, perché il codice è sincrono e alla fine verrà visualizzato solo un repaint. Non sono sicuro che tutto sia ancora più collegato :) – Ian

risposta

6

penso che si frainteso la domanda. L'ho letto come se chiedessi di aggiungere un elemento al DOM, quindi ritarda ogni ulteriore elaborazione fino al prossimo tick. Pertanto:

document.appendChild(element); 
setTimeout(function() { 
    resumeProgramFlowFromHere(); 
}, 0); 
// nothing here 

Questo è utile quando si desidera assicurarsi che ci sia un riflusso/repaint prima qualche operazione in termini di tempo avviene (per dare agli utenti un feedback visivo). I browser forzano già un repaint in certain circumstances, ma quando non lo fanno, questa tecnica può essere utile.

È possibile trovare ulteriori informazioni here e here.


Questa è la mia interpretazione della domanda, ma io lo trovo troppo confuso, probabilmente perché non è chiaro cosa si intende per eventi. E ci sono altre domande discutibili su quel sito, l'essere più strana:

Qual è il concetto di “funzioni come oggetti” e in che modo incide portata variabile?

Questo semplicemente non ha senso per me. Ok, le funzioni sono oggetti in JavaScript e gli ambiti sono anche correlati alle funzioni, ma questi sono argomenti distinti. Il fatto che le funzioni siano oggetti non ha nulla a che fare con l'ambito.

Quindi il mio consiglio è di portare quelle domande di intervista con un pizzico di sale.

0

Ci sono situazioni in cui si incontrano bug che richiedono questa tecnica per risolvere. Non è specifico per accodare un elemento; questo è solo un caso d'uso.

Ho riscontrato questo di tanto in tanto facendo particolari tipi di animazioni in cui l'impostazione di più proprietà css3 allo stesso tempo non determina il corretto ridisegno del browser.

Anche se non ho esempi di codice del caso precedente, è possibile vedere dove utilizzo la tecnica sul mio sito http://popped.at. Cerca in questo file, , e cerca "// il timeout di 0 ms è necessario per IE9". In questo caso, c'era un problema in IE9 in cui il canvas non veniva aggiornato correttamente.

(Il sito non funziona nel backend in questo momento, che è il motivo per cui il suo buio. Sto lavorando su questo.)

Problemi correlati