Подтвердить что ты не робот

Обход перехода и мгновенное изменение свойства

Я хочу обойти переход CSS и мгновенно изменить свойство.
Я попытался установить transition-duration в 0s перед изменением, а затем вернул исходное значение transition-duration:

$('div').css('width', '200px').delay(1000).queue(function() {
    $(this).css({
        transitionDuration: '0s',
        msTransitionDuration: '0s',
        mozTransitionDuration: '0s',
        webkitTransitionDuration: '0s',
        oTransitionDuration:'0s'
    }).css('width', '10px').css({
        transitionDuration: '2s',
        msTransitionDuration: '2s',
        mozTransitionDuration: '2s',
        webkitTransitionDuration: '2s',
        oTransitionDuration:'2s'
    })
})​

Fiddle
Это явно не работает.

Я понимаю, что spec не определяет это поведение для этого:

Поскольку эта спецификация не определяет, когда вычисленные значения изменяются, и, следовательно, какие изменения в вычисленных значениях считаются одновременными, авторы должны знать, что изменение любого из свойств перехода небольшое количество времени после внесения изменений, которые могут приводят к поведению, которое варьируется между реализациями, поскольку изменения могут рассматриваться как одновременные в некоторых реализациях, но а не другие.

Есть ли простой способ сделать это?

Примечание. Свойство, которое я изменяю, transform, поэтому .animate() не будет вариантом.

4b9b3361

Ответ 1

Поскольку никто другой не отправляет правильный ответ, здесь идет:

$('div').css('width', '200px').delay(1000).queue(function() {
    $(this).css({transition: '0s', width: '10px'}).delay(1).queue(function() {
        $(this).css({transition:'2s'});
    });
},1000)​;

FIDDLE

Или если это иначе:

$('div').css({
    transition: '0s'
  }).css('width', '200px').delay(1000).queue(function() {
      $(this).css({width: '10px', transition: '2s'});
});

FIDDLE

jQuery должен нормализовать префиксы поставщиков в эти дни, поэтому вам не нужно вводить их самостоятельно.


Проблема здесь в том, что jQuery присоединяет все стили сразу, сохраняя только последние стили, перезаписывая предыдущие стили одного и того же свойства CSS, даже не делая перерисовку DOM, а тестирование с помощью собственного javascript, похоже, делает то же самое, поэтому, вероятно, браузер пытается избежать ненужных переходов, добавив стиль, чтобы изменить его в следующей строке кода, так что:

$('div').css({
    transition: '0s',
    width: 200
}).css({
    transition: '3s',
    width: 10
});

не будет работать, поскольку добавляется только последний стиль.

Здесь delay() вступает в игру, вопрос OP уже использует delay(), поэтому нет причин не использовать его, но удаление delay(), конечно, вызовет указанную выше проблему, t нарисуйте первый стиль, но только последний и т.д.

Поскольку delay() - действительно просто причудливый тайм-аут, он эффективно отменяет выполнение второй настройки стилей, вызывая два перерисовки браузера.

Поскольку это, скорее всего, проблема с браузером, а не то, что мы можем изменить, отложить настройку второго стиля - это единственный способ сделать эту работу, и использование задержки будет по-прежнему работать, даже если оно будет установлено всего на 1 миллисекунду, или можно отложить выполнение с регулярным таймаутом, что является обычным способом отсрочить выполнение script:

$('div').css({
    transition: '0s',
    width: 200
});

setTimeout(function() {
    $('div').css({
        transition: '3s',
        width: 10
    });
});

FIDDLE

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

Ответ 2

Если у вас есть контроль над CSS

Самый простой способ - привязать анимацию к некоторому классу, а затем, в какой момент вы хотите, чтобы анимация больше не обходилась, вы добавляете класс, иначе анимация никогда не будет установлена. Если наоборот, вы обычно хотите анимацию, но иногда хотите обойти ее, а затем добавить класс по умолчанию и удалить его во время обхода.

Пример CSS

div{
    height: 100px;
    width: 200px;
    background: red;
}
div.doTransition {
    width: 10px;
    transition: width 2s linear;
    -ms-transition: width 2s linear;
    -moz-transition: width 2s linear;
    -webkit-transition: width 2s linear;
    -o-transition: width 2s linear;
}

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

Ответ 3

Настройте класс переопределения, который отключит css-переходы для элемента, к которому применяется, !important идеально подходит для этого:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

Теперь вы можете toggleClass переключить желаемое поведение (плавный переход и мгновенное изменение):

$('div').
toggleClass('notransition', true). //or false!
css('width', '200px');

Спрятано. ИМО одним из преимуществ этого подхода заключается в том, что у вас есть четкое разделение между стилями элементов по умолчанию и отключением всех плавных флагов анимации. Это также очень "обертываемый" многоразовый подход, то есть вы можете легко добавить необязательное логическое свойство к вашим существующим методам, которые указывали бы, должно ли оно выполняться с переходами.

NB: иногда вам может понадобиться отключить переходы на странице в целом по любым причинам производительности /UX. В этом случае вы можете сменить селектор на .notransition * и отключить переход для всех элементов-потомков.

Ответ 4

Проблема заключается в том, что, поскольку нет причин для замедления браузера и выполнения каждой операции отдельно, он объединяет их и делает оба одновременно. Запрос offsetHeight - это один из способов заставить его выполнять каждую операцию отдельно, так как она должна пересчитать высоту. http://jsfiddle.net/markasoftware/6cTeY/15/ отлично работает

Ответ 5

Это единственный способ заставить его работать. jQuery кажется немного упрямым.

http://fiddle.jshell.net/8qTpe/1/

P.S. В вашем подходе есть некоторые ошибки:

  • Вы повторно настраиваете до 200px до задержки, тем самым используя настройки CSS по умолчанию.

  • Вы измените размер до 10px до того, как переход перехода на 2s.

Теперь jQuery, кажется, применяет все настройки CSS в строке, поэтому почему все это не работает.

Ответ 6

Я бы выбрал довольно чистое решение для CSS

HTML

<div id="foo"></div>
<button class="out">out</button>
<button class="in">in</button>

JS

$('button.out').click(function(){console.log($('#foo').addClass);$('#foo').addClass('out')})
$('button.in').click(function(){$('#foo').removeClass('out')})

CSS

div{
    height: 100px;
    width: 10px;
    background: red;

    transition: width 0s linear;
    -ms-transition: width 0s linear;
    -moz-transition: width 0s linear;
    -webkit-transition: width 0s linear;
    -o-transition: width 0s linear;
}
div.out {
    width: 200px;
    transition: width 2s linear;
    -ms-transition: width 2s linear;
    -moz-transition: width 2s linear;
    -webkit-transition: width 2s linear;
    -o-transition: width 2s linear;

}

http://jsfiddle.net/6cTeY/19/

Ответ 7

Я обычно делаю это в этой ванильной моде JS.

FIDDLE

HTML

Предположим, что у вас есть элемент

<div id="element"></div>

CSS

Предположим, что у вашего элемента уже есть переходы CSS, а background: green

#element {
    background: green;
    width: 200px;
    height: 200px;
    -webkit-transition: 'all 0.5s ease-out';
    -moz-transition: 'all 0.5s ease-out';
    -ms-transition: 'all 0.5s ease-out';
    -o-transition: 'all 0.5s ease-out';
}

JS

Элемент имеет переходы CSS, но мы хотим мгновенно изменить фон элемента на BLUE.

Сразу после этого мы хотим вернуть нормальное поведение элемента, чтобы мы могли анимировать его на RED.

Нам нужно отключить переходы на мгновение и восстановить их сразу после.

// grab the element
var element = document.getElementById('element');

// removeTransitions
element.style.webkitTransition   = 'none';
element.style.mozTransition      = 'none';
element.style.msTransition       = 'none';
element.style.oTransition        = 'none';

// apply desired 'instant' property
element.style.background         = 'blue'; // is applied instantly

// this 10ms timeout is necessary for the transitions to be active again
setTimeout(function() {
    element.style.webkitTransition   = 'all 5s ease-out';
    element.style.mozTransition      = 'all 5s ease-out';
    element.style.msTransition       = 'all 5s ease-out';
    element.style.oTransition        = 'all 5s ease-out';

    // apply desired 'animated' property
    element.style.background         = 'red';  // is applied smoothly
}, 10);