I
I
Ilya Pestov2013-05-29 03:15:31
JavaScript
Ilya Pestov, 2013-05-29 03:15:31

How to implement "alternate" code execution?

Good day dear habrazhiteli. I myself am an inexperienced coder and faced the following problem: I want to perform an animation (transition registered in css), but the nature of modern rendering engines (multitasking, executing one line is already working on another ... or how to say it right) does not allow me to do this.

Example:

$('.nextMonthArrow').click(function() {
  createCalendar(1, "nextMonth"); // 60ms на создание
  var content = $('.calendarBody').html();
  $('.calendarBody').html('<div id="calendarTransform">'+content+'</div>');
  setTimeout(function(){$('#calendarTransform').css({'margin-left': -step, 'width': step*2})}, 1);
});


Literally randomly, I decided to use setTimeout and it turned out to work even for one millisecond. But if you remove the timeout, then there is no animation. As far as I understand, the browser has not yet had time to read the css transition, but the margin from js has already processed (.js is connected much later than .css). Why saves setTimeout? What other options are there?

No - I don't want to use $.animate();
Does anyone have a snippet of cross-browser handling of the Transition Event?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Keith, 2013-05-29
@ilusha_sergeevich

The above was correct, I'll try to add.
You create DOM( calenderTrasform) and assign margin-left / width in the same event tick. And roughly speaking, your new html comes into live DOM already with margin-left / width - that is, the browser does not fix these changes, therefore transition is not called. And using setTimeout, you transfer the assignment of margin-left / width to the next tick in the event loop - and after your “click” function has completed, the browser will “get acquainted” with the new nodes in the house in between, and when the timer function changes the margin -left, the browser will capture this and run the transition. And the timer in this case is the best solution - without the need to force the browser to recalculate the styles:

// ...
$('.calendarBody').html('<div id="calendarTransform">'+content+'</div>');
var $transform = $('#calendarTransform'),
       styles  = getComputedStyle($transform[0]);
styles['margin-left'];
styles['width'];

$transform.css({'margin-left': -step, 'width': step*2})}, 1);

This also applies to removing "display:none" - assigning all other styles in the same tick will not be seen as a change by the browser.

D
deleted-mifki, 2013-05-29
@deleted-mifki

Because you are trying to animate a newly created element, and with a timeout, this happens already on the next iteration of the event loop. Well, by the way, using the timer in this way (you can even write 0 there, apparently) is a completely normal approach.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question