L
L
Luhashan2022-01-03 16:39:32
css
Luhashan, 2022-01-03 16:39:32

Why doesn't transitionend fire and what exactly happens when changing in the DOM tree?

There is a very trivial code that works as expected:

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <style type="text/css">
    	.opacity {
    		opacity: 0;
    	}
    </style>
</head>
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div id="move" style="transition-duration: 1s;">4</div>
    <script>
    $(document).ready(function() {
        function on_transitionend(event) {
        	$(this).toggleClass('opacity');
        }
        $('div').on('transitionend webkitTransitionEnd oTransitionEnd', on_transitionend);
        $('#move').toggleClass('opacity');
    });
    </script>
</body>
</html>

But, if the element is permuted in the on_transitionend() handler, then its transition-duration property stops working, and accordingly, the handler is not called either:
function on_transitionend(event) {
        	$(this).insertBefore($('div').get(0));
        	$(this).toggleClass('opacity');
        }

At the same time, the browser can see that all the properties and handlers of the element that was rearranged are in place.
If, after rearranging the element, you try to call the transitionend handler not from the main thread, but via setTimeout, then everything works as expected:
function on_transitionend(event) {
        	$(this).insertBefore($('div').get(0));
        	var el = this
        	setTimeout(function() {$(el).toggleClass('opacity');}, 0);
        }

Accordingly, the question is, why is this happening and what exactly happens after changing the DOM tree?
I have only one hypothesis: when the DOM of the tree changes, an API event is fired, which is placed in the event queue with the highest priority. Accordingly, after the completion of the main thread, it fires and produces a kind of "remapping" of the entire DOM tree, including handlers and properties. After that, the zero timeout is triggered and everything is OK. If so, is it possible to call this "remapping" from js code?
Many thanks in advance for the clarifications!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Dubrovin, 2022-01-03
@luhashan

Hypothesis: when changing the DOM of the tree, an API event is fired, which is placed in the event queue with the highest priority. Accordingly, after the completion of the main thread, it fires and produces a kind of "remapping" of the entire DOM tree, including handlers and properties.

This is 100% wrong. I didn't even understand what you wrote.
Since we have 2 actions related to rendering, they are optimized. That is why all actions with visualization are done as close as possible. In your case. You do a permutation of the node home. This causes the elements to be redrawn. She sees "Yeah, we also change the class -> we change it right away -> and then draws the house." Since she draws with the effects already applied, the event does not fire.
Why does the timer work? I think it becomes clear.
We draw a house-> The timer independently works and hangs a class-> We draw again. The event is happening.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question