Firefox在CSS3过渡之前没有更新DOM

时间:2012-12-11 01:19:39

标签: javascript dom css3

我正在尝试构建一个非常简单的滑块。我想为动画和js使用CSS3过渡,将animate-in和animate-out类按顺序应用于各个帧。

我在jsfiddle编写了一个基本预期功能的工作演示:http://jsfiddle.net/7myKg/3/

这很简单。通过应用动画类来动画帧,并通过应用动画类来动画化。例如,这将显示第二帧:

<div class="slider" id="slider">
    <ul>
        <li id="frame1" class="animate-out"><p>one</p></li>
        <li id="frame2" class="animate-in"><p>two</p></li>
        <li id="frame3"><p>three</p></li>
    </ul>
</div>​

在我可以动画帧之前,我需要确保它被重置,帧必须不转换到它的重置状态。为了达到这个目的,我在帧中添加了内联样式,将其转换持续时间设置为0,然后再删除它的动画类。目前,这可以在Chrome中使用。我遇到的问题是Firefox似乎在DOM反映了元素样式的变化之前应用了animate-in类,这导致元素/帧向后过渡。通过在Firefox中运行演示而不是解释更容易看到。我添加了一个带延迟的setTimeout包装来演示我期望它的行为。

我错过了什么?为什么Firefox不能立即更新DOM元素?

我从头开始构建这个作为学习经验,因为我认为这是一个奇怪的问题,我能够解决。它不是用于生产,至少当然不是为了生产。出于这个原因,我不想使用许多现有的解决方案或插件之一。

注意:这是我的第一个问题所以任何建设性的提示,如果我在将来如何提出更好的问题方面做错了,我将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:2)

-moz过渡:左

我开始摆弄,但更喜欢从一个干净的页面开始。

跳出来的第一个问题是-moz-transition:被省略-o-transition:。 我现在非常累,真的不能打扰看,但上次我检查时,所有的浏览器仍然需要自己的前缀,IE(9)仍然没有'支持过渡。

编辑:Apparently since FF16, the -moz- prefix isn't needed

其次;你没有在你的CSS声明中说明你想要转换的样式属性。即-moz-transition:left 1s;

第三;我不记得细节了,因为我认为信息的有用性很小,但我记得读到有关携带参数的setTimeout,因为它不是普遍稳定的。我可能已经在developer.mozilla的某个地方看过了。甚至可能在某个地方到过这里。

编辑:Typically IE specific。我还是只使用一个简单的匿名函数。

正如我所说,我开始使用代码,但更愿意重写。

就像我也说的那样,我很累(接近睡觉),所以我现在不会这样做,但可能明天。在此期间,尝试修复这三点。

更新

发布编辑(我对-moz-前缀是对的: - )

我无法帮助自己JsFiddle

HTML

<div>
    <input type="checkbox" id="overflowHidden"><p>overflow: hidden</p>
    <button id="next">Next</button>
</div>
<div class="slider">
    <ul id="slider" class="a">
        <li id="frame3"><p>three</p></li>
        <li id="frame1"><p>one</p></li>
        <li id="frame2"><p>two</p></li>
    </ul>
</div>​

CSS

input {
    display:inline-block;
    margin:10px 0px 0px 10px;
}
button {
    display:inline-block;
    margin:0px 0px 0px 10px;
    vertical-align:2px;
}
p {
    display:inline-block;
    margin:0px 0px 0px 5px;
    vertical-align:2px;
}
.slider {
    margin: 2em auto;
    padding: 0;
    width: 200px;
    height: 200px;
}
#slider {
    margin: 0;
    padding: 0;
    list-style-type: none;
    position: relative;
    width: 100%;
    height: 100%;
}
.slider li {
    margin: 0;
    padding: 0;
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0%;
    -o-transition:left 1s ease-in-out;
    -webkit-transition:left 1s ease-in-out;
    -moz-transition:left 1s ease-in-out;
    transition:left 1s ease-in-out;
}
#frame1 {
    background:#e08080;
}
#frame2 {
    background:#e0e080;
}
#frame3 {
    background:#8080e0;
}
#slider.a #frame1{
    left: 0%;
}
#slider.a #frame2{
    left: -100%;
}
#slider.a #frame3{
    left: 0%;
}
#slider.b #frame1{
    left: 0%;
}
#slider.b #frame2{
    left: 0%;
}
#slider.b #frame3{
    left: -100%;
}
#slider.c #frame1{
    left: -100%;
}
#slider.c #frame2{
    left: 0%;
}
#slider.c #frame3{
    left: 0%;
}

的JavaScript

(function () {
    window.addEventListener("load", function () {
        var slider = document.getElementById("slider");
        document.getElementById("next").addEventListener("click", function () {
            var c = slider.getAttribute("class");
            c = c === "a" ? "b" : c === "b" ? "c" : c === "c" ? "a" : c;
            slider.setAttribute("class", c);
            slider.appendChild(slider.getElementsByTagName("li")[0]);
        }, false);
        // adding a toggle for overflow just for demo
        document.getElementById("overflowHidden").addEventListener("change", function () {
            if (this.checked) {
                slider.style.overflow = "hidden";
            } else {
                slider.removeAttribute("style");
            }
        }, false);
    }, false);
}());

当然,有很多不同的方法可以完成这类事情。作为一项规则,我首先想象我想要什么,并从那里开始构建,而不是尝试使用特定方法以特定方式使某些东西工作。

JavaScript完成的大部分工作可以使用@keyframes传递给CSS,而不是使用多个元素。但它总是取决于确切的情况不是吗?

虽然考虑了所有需要的2个颜色面板,其中一个可能是背景。这允许只需要移动一个元素(将其滑动,将背景设置为相同颜色,无需转换即可将其发回,更改颜色,并且可以再次滑动)。

虽然很少有学习项目很有趣(我知道),但它们可能会失控,有时候我们学会了所有的东西并回归基础是很好的。

我真的不是故意光顾。好运: - )