过渡不正确执行



我正在尝试执行图像库的过渡。当画廊过渡到下一张幻灯片时,我将其仅在当前幻灯片的左侧,然后通过在其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值,以便下一个幻灯片将在当前幻灯片上滑动

脚本:

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中的错误?

就像它发生在许多UI框架中,它们仅在一个线程中执行所有UI操作(Windows表单,WPF ...),在用户代码执行时,大多数布局操作都会阻止。为什么?好吧,尽管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';

最新更新