转换未正确执行

时间:2014-03-09 21:49:40

标签: javascript css

我正在尝试执行图片库的转换。当图库转换到下一张幻灯片时,我会将它放在当前幻灯片的左侧,并通过转换为left样式将其滑过当前幻灯片。

我目前的加价:

 <section id="nd-gallery">
    <div class="nd-slide nd-slide-current">
        slide 1
    </div>
    <div class="nd-slide nd-slide-next">
        slide 2
    </div>
</section>

相关CSS:

#nd-gallery{
    position:relative;
    height:100px;
    width:100px;
}

#nd-gallery > .nd-slide{
    position:absolute;
    height:100px;
    height:100px;
    outline:1px solid red;
    left:-40px;
}

#nd-gallery > .nd-slide.nd-slide-current{
    z-index:5;
    left:0;
}

所以,默认情况下,我通过将幻灯片向左移动40px来偏移幻灯片(显然我会在这个演示之外用更大的偏移量更好地隐藏它们)

现在,有了一些脚本,我想:

  • 将新的left值应用到下一张幻灯片以抵消它(为了演示的目的,50px将当前幻灯片的下一张幻灯片偏移一半)

  • 指定适当的转换属性

  • 指定新的left值,以便下一张幻灯片将滑过当前幻灯片

SCRIPT:

var next = document.querySelector('.nd-slide-next');
next.style.left = '-50px';
next.style.transitionProperty = 'left';
next.style.transitionDuration = '5s';
next.style.left = '0';

然而,当我运行此时,下一张幻灯片显示在当前幻灯片的顶部而没有转换:

http://jsfiddle.net/ACdc7/4/

注意:显然Firefox正确执行转换。在Windows 7上的Chrome v.32中,不会执行转换。任何人都可以指出我做错了什么,或者我正在处理Chrome中的错误吗?

1 个答案:

答案 0 :(得分:0)

与许多只在一个线程(Windows窗体,WPF ...)中执行所有UI操作的UI框架一样,大多数布局操作在用户代码执行时被阻止。为什么?好吧,当Javascript代码正在执行时,浏览器根本没有响应,因为它的UI线程被占用处理代码。因此,如果在将控制权放弃到浏览器之前多次更改同一属性的值,则只保留最后一个值。当您更改(例如)元素的left值时,如果您可以稍后在同一事件处理程序中更改它,那么通过布局过程将浪费处理能力。因此,浏览器只是创建一个待处理布局操作的队列,并在没有其他任何操作时执行它们。

应用于您的案例,浏览器会将操作{next.style, 'left', -50px}添加到队列中。再次向左更新时,浏览器不会添加新操作。由于有一个待处理的相同,它只是更新它。因此,对于浏览器,您不是将left属性从-50px更改为0px,而只是将其设置为0px。

left设置为-50px后,您需要放弃对浏览器的控制。然后,将其设置回0px。你可以这样做:

var next = document.querySelector('.nd-slide-next');
next.style.left = '-50px';
setTimeout(function() {
    next.style.transitionProperty = 'left';
    next.style.transitionDuration = '5s';
    next.style.left = '0';
}, 10);

如果强制执行同步布局(通常不合适),它也可以工作。您可以通过访问DOM节点的某些属性来实现此目的,例如offset-client-属性。这些属性总是返回最新的值,因此,如果布局操作挂起,浏览器将停止执行javascript代码,执行布局并继续执行:

var next = document.querySelector('.nd-slide-next');
next.style.left = '-50px';
var offset = next.offsetLeft; //force layout. The broswer know acknowledges that next.style.left is -50px.
next.style.transitionProperty = 'left';
next.style.transitionDuration = '5s';
next.style.left = '0';