2016-11-11 62 views
1

我想实现的是从js更改一些属性(background-color在上面的代码中)两次,以便过渡将在它们之间运行,但不是从以前的状态到第一个。上面的代码几乎从来没有工作,因为超时设置为零,它几乎总是工作时,它至少设置为10,它始终在我的机器上时,我将它设置为100.我还想要完全避免超时和以太线性运行代码或基于适当的事件回调(到目前为止我没有发现任何有用的)。CSS过渡与纯JS没有延迟

下面是一个例子(also on jsFiddle):我管理的绿色环保和使用transitionend处理(其中,不幸的是,还要求供应商在使用很短的过渡做

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

前缀  — 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处理程序一样简单,直到transitionend。 – 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对),不幸的是。 – Grief