2016-11-11 4 views
1

Чего я хочу добиться, это изменить некоторое свойство (background-color в коде выше) дважды из js, чтобы переход между ними выполнялся, но не от предыдущего состояния до первого. Код выше почти никогда не работает, потому что тайм-аут установлен на ноль, он работает почти всегда, когда он установлен как минимум на 10, и он всегда работает на моей машине, когда я устанавливаю его на 100. То, что я также хочу, - это полностью исключить таймауты и эфир запускайте код линейно или на основе соответствующего обратного вызова события (я пока не нашел полезного).Переход CSS с чистым JS без задержки

Вот пример (also on jsFiddle):

var outter = document.getElementById('outter'); 
 
var test = document.getElementById('test'); 
 

 
test.onclick = function() { 
 
    outter.removeChild(test); 
 
    test.style.backgroundColor = 'green' 
 
    outter.appendChild(test); 
 
    setTimeout(function() { 
 
    test.style.backgroundColor = 'red' 
 
    }, 0); 
 
}
#test { 
 
    position: fixed; 
 
    left: 2em; 
 
    right: 2em; 
 
    top: 2em; 
 
    bottom: 2em; 
 
    background-color:red; 
 

 
    transition-duration: 2s 
 
}
<div id=outter> 
 
    <div id=test></div> 
 
</div>

+1

Так по щелчку, вы хотите, чтобы фон немедленно зеленеть, а затем провести две секунды перехода от зеленого до красного? –

+0

@ T.J.Crowder Точно! Самое главное здесь слово «немедленно» – Grief

+0

Я не понимаю, желая перейти от A к B сразу, а от A до B, но с задержкой. Вы уже на B. – Crowes

ответ

2

мне удалось сделать это с помощью очень короткий переход, когда будет зеленый и использование transitionend обработчиков (которые, к сожалению, до сих пор требуют поставщика префиксы   — yeesh).

Следующие работы для меня работают с Firefox, Chrome и IE11. (Следует отметить, что вы не должны использовать классы, я предпочитаю, чтобы сохранить стиль в CSS, вы могли бы использовать outter.style.transitionDuration = "2s"; и такие.)

var outter = document.getElementById('outter'); 
 
var test = document.getElementById('test'); 
 

 
function onTransition(element, handler, add) { 
 
    var method = (add ? "add" : "remove") + "EventListener"; 
 
    element[method]("transitionend", handler, false); 
 
    element[method]("mozTransitionEnd", handler, false); 
 
    element[method]("webkitTransitionEnd", handler, false); 
 
} 
 

 
test.onclick = function() { 
 
    // If we're running... 
 
    if (outter.classList.contains("green")) { 
 
    // ...reset 
 
    onTransition(outter, greenToRed, false); 
 
    onTransition(outter, redDone, false); 
 
    outter.classList.remove("green", "red"); 
 
    } 
 
    onTransition(outter, greenToRed, true); 
 
    outter.classList.add("green"); 
 
}; 
 

 
function greenToRed() { 
 
    onTransition(outter, greenToRed, false); 
 
    onTransition(outter, redDone, true); 
 
    outter.classList.add("red"); 
 
} 
 
function redDone() { 
 
    onTransition(outter, redDone, false); 
 
    outter.classList.remove("green", "red"); 
 
}
#test { 
 
    position: fixed; 
 
    left: 2em; 
 
    right: 2em; 
 
    top: 2em; 
 
    bottom: 2em; 
 
    background-color: red; 
 
} 
 

 
.green #test { 
 
    background-color: green; 
 
    transition-duration: 0.0001s; 
 
} 
 
.red #test { 
 
    transition-duration: 2s; 
 
    background-color: red; 
 
}
<div id=outter> 
 
    <div id=test></div> 
 
</div>

Выше только доказательство Конечно, концепция; он может быть доработан и очищен честно.

+0

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

+0

@Grief: Вы имеете в виду кликнуть по нему, а затем щелкнуть его снова в течение двух секунд от зеленого до красного? И если да, что вы хотите? Игнорировать второй клик? Начать сначала? –

+0

Я хотел бы начать анимацию, как в исходном фрагменте. Игнорирование выполняется так же просто, как удаление обработчика onclick до перехода. – Grief

3

без таймаутов:

var outter = document.getElementById('outter'); 
 
var test = document.getElementById('test'); 
 

 
test.onmousedown= function() { 
 
    test.style.transitionDuration = "0s"; 
 
    test.style.backgroundColor = 'green'; 
 
}; 
 

 
test.onmouseup= function() { 
 
    test.style.transitionDuration = "2s"; 
 
    test.style.backgroundColor = 'red'; 
 
};
#test { 
 
    position: fixed; 
 
    left: 2em; 
 
    right: 2em; 
 
    top: 2em; 
 
    bottom: 2em; 
 
    background-color:red; 
 
}
<div id=outter> 
 
    <div id=test></div> 
 
</div>

+0

Мне очень нравится ваше решение, потому что это самый хитрый, и он будет работать отлично в тех же условиях, что и я описал, однако мне нужно запустить эту анимацию не только с кликами, и я не могу полагаться на ввод пользователя (mousedown/mouseup pair) здесь, к сожалению. – Grief