通过JavaScript分配时,CSS转换不起作用

时间:2011-11-21 10:49:22

标签: javascript css css3 css-transitions

我在尝试通过JavaScript将幻灯片应用CSS3过渡时遇到了一些重大问题。

基本上JavaScript会获取幻灯片中的所有幻灯片,并将CSS类应用于正确的元素以提供良好的动画效果,如果没有CSS3过渡支持,它将只应用样式而不进行过渡。

现在,我的'小'问题。所有工作都按预期工作,所有幻灯片都获得正确的样式,代码运行没有错误(到目前为止)。但是指定的转换不起作用,即使应用了正确的样式。此外,当我通过检查员自己应用样式和过渡时,样式和过渡也会起作用。

由于我自己找不到合乎逻辑的解释,我以为有人可以回答这个问题,好吗?

我已经汇总了一些代码现在的例子:http://g2f.nl/38rvma 或者使用JSfiddle(无图像):http://jsfiddle.net/5RgGV/1/

3 个答案:

答案 0 :(得分:48)

要使transition工作,必须要做三件事。

  1. 元素必须明确定义属性,在本例中为opacity: 0;
  2. 元素必须定义过渡:transition: opacity 2s;
  3. 必须设置新属性:opacity: 1
  4. 如果您动态分配1和2,就像您在示例中一样,则需要在3之前有一个延迟,以便浏览器可以处理请求。调试它时它起作用的原因是你通过单步调试来创建这个延迟,从而为浏览器提供了处理时间。延迟分配.target-fadein

    window.setTimeout( function() { slides[targetIndex].className += " target-fadein"; }, 100 ); 
    

    或者直接将.target-fadein-begin放入HTML中,以便在加载时对其进行解析,并为转换做好准备。

    向元素添加transition不会触发动画,而是更改属性。

    演示:http://jsfiddle.net/ThinkingStiff/QNnnQ/

    HTML:

    <div id="fade1" class="fadeable">fade 1 - works</div>
    <div id="fade2">fade 2 - doesn't work</div>
    <div id="fade3">fade 3 - works</div>
    

    CSS:

    .fadeable {
        opacity: 0;
    }
    
    .fade-in {
        opacity: 1;
        transition:             opacity 2s;
            -moz-transition:    opacity 2s;
            -ms-transition:     opacity 2s;
            -o-transition:      opacity 2s;
            -webkit-transition: opacity 2s;
    }
    

    脚本:

    //works
    document.getElementById( 'fade1' ).className += ' fade-in';
    
    //doesn't work
    document.getElementById( 'fade2' ).className = 'fadeable';
    document.getElementById( 'fade2' ).className += ' fade-in';
    
    //works
    document.getElementById( 'fade3' ).className = 'fadeable';
    window.setTimeout( function() {
    
        document.getElementById( 'fade3' ).className += ' fade-in';
    
    }, 100);
    

答案 1 :(得分:4)

欺骗布局引擎!

function finalizeAndCleanUp (event) {
    if (event.propertyName == 'opacity') {
        this.style.opacity = '0'
        this.removeEventListener('transitionend', finalizeAndCleanUp)
    }
}
element.style.transition = 'opacity 1s'
element.style.opacity = '0'
element.addEventListener('transitionend', finalizeAndCleanUp)
// next line's important but there's no need to store the value
element.offsetHeight
element.style.opacity = '1'

如前所述,transition通过从状态 A 插值到状态 B 来工作。如果您的脚本在同一功能中进行更改,则布局引擎无法分离状态 A 结束且 B 开始的位置。除非你给它一个提示。

由于没有官方方式来提示,因此您必须依赖某些功能的副作用。在这种情况下,.offsetHeight getter隐式地使布局引擎停止,评估和计算所有已设置的属性,并返回一个值。通常,这应该避免出现性能影响,但在我们的情况下,这正是所需要的:状态整合。

为完整性添加了清理代码。

答案 2 :(得分:1)

有些人问过为什么会有延误。该标准希望允许多次转换(称为样式更改事件)立即发生(例如,元素在旋转到视图的同时淡入)。不幸的是,它没有定义一种明确的方法来分组您想要同时发生的转换。相反,它允许浏览器任意选择哪些转换同时发生它们被调用的距离。大多数浏览器似乎都使用刷新率来定义此时间。

如果您需要更多详细信息,请参阅以下标准: http://dev.w3.org/csswg/css-transitions/#starting