Как удалить css-переходы без задержки?

Я хочу, чтобы переход css-свойства был плавным, тогда я хочу немедленное изменение значения свойства css, а затем я хочу снова привязать переход. Чтобы лучше понять следующий пример:

if ($(".marquee").height() < $(".marquee-content").outerHeight(true)) {
  $(".marquee-content").clone().appendTo($(".marquee-wrapper"));
}
$('.marquee-wrapper').css("transition", "transform 3s linear");
$('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)");

setInterval(function() {
  
  $('.marquee-wrapper').css("transition", "none");
  $('.marquee-wrapper').css("transform", "translateY(100px)"); //This should Immediately change translateY to 100px without smooth transition. But this doesn't happen without adding a delay before the below written line
  
  // Its weird why javascript engine executes the below line before executing this line

  $('.marquee-wrapper').css("transition", "transform 3s linear");
  $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)");

}, 3000);
.marquee {
  margin: auto;
  width: 600px;
  height: 200px;
  overflow: auto;
}

.marquee-wrapper {
  transform: translateY(0);
}

.marquee-content {
  margin: 0;
  padding: 30px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="marquee">
  <div class="marquee-wrapper">
    <div class="marquee-content">
      Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington 👠Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being
      loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq
      = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods e.g to remove the marquee plugin from your element simply use $mq.marquee('destroy');.
      Similarly you can use pause the marquee any time using $mq.marquee('pause');.
    </div>
  </div>
</section>

Ответ 1

Группировка свойств CSS transition и transform в одном утверждении дает правильный результат без необходимости использовать задержку 100 мс:

$('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" });
setInterval(function () {
    $('.marquee-wrapper').css({ transition: "none", transform: "translateY(100px)" });
    $('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" });
}, 3000);

if ($(".marquee").height() < $(".marquee-content").outerHeight(true)) {
    $(".marquee-content").clone().appendTo($(".marquee-wrapper"));
}

$('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" });

setInterval(function () {
    $('.marquee-wrapper').css({ transition: "none", transform: "translateY(100px)" });
    $('.marquee-wrapper').css({ transition: "transform 3s linear", transform: "translateY(-" + $(".marquee-content").outerHeight(true) + "px)" });
}, 3000);
.marquee {
  margin: auto;
  width: 600px;
  height: 200px;
  overflow: auto;
}

.marquee-wrapper {
  transform: translateY(0);
}

.marquee-content {
  margin: 0;
  padding: 30px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="marquee">
  <div class="marquee-wrapper">
    <div class="marquee-content">
      Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington 👠Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being
      loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq
      = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods e.g to remove the marquee plugin from your element simply use $mq.marquee('destroy');.
      Similarly you can use pause the marquee any time using $mq.marquee('pause');.
    </div>
  </div>
</section>

Ответ 2

Я объясню вам, почему это происходит.
Я имел дело с анимацией javascript, и есть много js-библиотек (сфокусированных на математике) с учетом операционных задержек (политики доступности ввода-вывода) и тайм-аутов.

В первом фрагменте кода у вас есть следующие операции:

$('.marquee-wrapper').css("transform", "translateY(100px)");
$('.marquee-wrapper').css("transition", "transform 3s linear");

Transform

Метод Css Transform использует операции на основе матрицы, которые имеют высокую вычислительную стоимость. Существуют фреймворки css-animation, которые используют графический процессор (с матричными операторами), который работает в несколько раз быстрее для достижения плавных графических операций в реальном времени.

Переход

Css Transition - еще одна графическая операция, но не модифицирует css-объект с чистым преобразованием [matrix op matrix], он использует правый одномерный оператор, что означает, что ваша css-матрица изменяется с помощью [matrix op array].

Затем выбираемый режим linear применяет линейную интерполяцию (возможно, всего несколько операторов интеграции) в позиции вашего элемента. Он имеет низкую вычислительную стоимость, что делает операцию перехода еще более быстрой для вычисления.

Это схема выполнения, выполняемая в виде временной шкалы:

transform         calculation-process
exec -----------------------------------------> applied
 |         |                            |        |
 |         |                            |        |
 |         |                            |        |
transition |     calculation-process    |        |
--------- exec ---------------------> applied --------- 

Поскольку jQuery в верхней части javascript выполняет неблокирующий код (для i/o зависимых функций и, если вы не кодируете его синхронизацию), который является базой асинхронной политики javascript, позволяет следующую операцию выполнить еще до прецедент заканчивается.

Ваше исправление с функцией тайм-аута гарантирует, что операция преобразования будет завершена до запуска следующего кода, но в качестве ограничения она будет работать только для клиентов с одинаковой вычислительной скоростью чем текущий клиентский процессор. (Если вы разрабатываете его на ПК, тогда он может выйти из строя в смартфоне)

Другим решением, которое я использую в своем коде, является использование обратных вызовов jquery. Посмотрите на jquery animate() doc, в котором показано:

.animate(свойства [, duration] [, easing] [, complete])

В вашем примере это будет что-то вроде:

$('.marquee-wrapper').animate({"transform": "translateY(100px)"}, function(){
    // this code runs after transform ends...
    $('.marquee-wrapper').css("transition", "transform 3s linear");
    $('.marquee-wrapper').css("transform", "translateY(-" + $(".marquee-content").outerHeight(true) + "px)");
});

Я нашел много полезных библиотек вокруг, чтобы "серьезно" играть с анимациями. Вот некоторые из библиотек, которые я использую:

d3.js
bounce.js
secuence.js
paper.js

Надеюсь, это поможет.

Обновление
Существует хороший ответ SO о переходах анимации и css здесь.

Ответ 3

Я думаю, что здесь есть несколько отличных ответов, рассказывающих вам, почему это работает, но если вы хотите больше анимации, поддерживаемой браузером, используйте jQuery animations.

$wrap = $(".marquee-wrapper")
$con = $(".marquee-content");
cHeight = $con.outerHeight(true)

if ($(".marquee").height() < cHeight) {
  $con.clone().appendTo( $wrap );
}

function animate() {
  $wrap.animate({
    top: "-=" + cHeight
  }, 3000, "linear", function() { 
    $(this).css("top", "0");
    animate();
  });
}

animate();

//Cache values
$wrap = $(".marquee-wrapper")
$con = $(".marquee-content");
cHeight = $con.outerHeight(true)

if ($(".marquee").height() < cHeight) {
  $con.clone().appendTo( $wrap );
}


function animate() {
  $wrap.animate({
    top: "-=" + cHeight //minus height from the value of top
  },
  3000, // milisecs of animations length
  "linear", // type of animations
  function() { //function to run after animation is complete
    $(this).css("top", "0");
    animate();
  });
}

animate(); //Run function in the beginning
.marquee {
  margin: auto;
  width: 600px;
  height: 200px;
  overflow: auto;
  position: relative;
}

.marquee-wrapper {  position: absolute;  }

.marquee-content {
  margin: 0;
  padding: 30px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="marquee">
  <div class="marquee-wrapper">
    <div class="marquee-content">
      Updates: Update (8 Mar 2016): Now plugin have new option: startVisible The marquee will be visible in the start if set to true. Thanks to @nuke-ellington 👠Update (24 Jan 2014): Note: people who been asking me how to use this plugin with content being
      loaded with Ajax, please read notes about this update. New methods added, so now after you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq = $('.marquee').marquee();, you start the plugin using var $mq
      = $('.marquee').marquee();, then you can pause, resume, togglepause, resume) and desestroy destroy toggle(pause, resume) and destroy toggle(pause, resume) and destroy methods e.g to remove the marquee plugin from your element simply use $mq.marquee('destroy');.
      Similarly you can use pause the marquee any time using $mq.marquee('pause');.
    </div>
  </div>
</section>