¿Cómo escribir una función que agregue un elemento al DOM y retrase el siguiente tic?

I recently found the following question online:

Write a function that takes an object and appends it to the DOM, making it so that events are buffered until the next tick? Explain why this is useful?

Aquí está mi respuesta:

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

Why did I set the interval to zero?

Según este artículo, setting the timeout to 0, delays the events until the next tick:

The execution of func goes to the Event queue on the nearest timer tick. Note, that’s not immediately. No actions are performed until the next tick.

Here's what I am uncertain of:

  • ¿Es correcta mi solución?
  • I cannot answer el porqué this approach is beneficial

For reference, I got this question from this website listing 8 JavaScript interview questions.

I'd also like to point out that I am asking this question for my own research and improvement and not as part of a code challenge, interview question, or homework assignment.

preguntado el 15 de mayo de 13 a las 03:05

This will allow you to see each item being added, one at a time (very quickly of course). If you just put it in a loop, the browser will wait until it's finished before repainting the screen. This is an example of synchronicity. -

Just for clarification, you're talking about the function being called inside of a loop, yes? Also, such an approach would cause multiple repaints, correct? -

I'm sorry, I don't know why I assumed this code was being called in a loop. I re-read just now. I guess my point was that if your function was being called in a loop (say from 0 to 9), you would/could see each element being appended, because there's a repaint since they're asynchronous. If you didn't use setTimeout and just called .appendChild en el mismo for loop, you'd see them all appear at once, because the code is synchronous and there will only be one repaint at the end. I'm not sure if that's all even related anymore :) -

The one thing I think I can say about this is that it depends on if you have code that expects the element to be in the DOM. For example, if you do: var div = document.createElement("div"); appendElement(div); and then expected div to be in the DOM, the code might not work properly, because it wouldn't be in the DOM yet -

2 Respuestas

I think you misunderstood the question. I read it as asking to append an element to the DOM, then delay any further processing until the next tick. Therefore:

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

That's useful when you want to make sure there is a reflow/repaint antes some time-consuming operation takes place (to give users visual feedback). Browsers already force a repaint in ciertas circunstancias, but when they don't, this technique can be useful.

Puedes encontrar más información aquí y aquí.


That's my interpretation of the question, but I find it confusing too, probably because it's not clear what they mean by Eventos. And there are other debatable questions on that site, the weirdest being:

What is the concept of “functions as objects” and how does this affect variable scope?

That simply makes no sense to me. Okay, functions are objects in JavaScript, and scopes are also related to functions, but those are distinct topics. The fact that functions are objects has nothing to do with scope.

So my advice is, take those interview questions with a grain of salt.

contestado el 23 de mayo de 17 a las 13:05

There are situations where you run into bugs that require this technique to fix. Its not specific to appending an element though; that's just one use case.

I've encountered this from time to time doing particular kinds of animations where setting multiple css3 properties at the same time doesn't trigger the browser to redraw correctly.

While I don't have code examples of the previous case, you can see where I use the technique on my site http://popped.at. Look in this file, http://www.popped.at/js/main.js, and search for "//the 0ms timeout is needed for IE9". In this case, there was an issue in IE9 where canvas wasn't being updated properly.

(The site isn't functioning in the backend at the moment, which is why its dark. I'm working on that.)

contestado el 15 de mayo de 13 a las 04:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.