【问题标题】:Transition not executing properly转换未正确执行
【发布时间】:2014-03-09 21:49:40
【问题描述】:

我正在尝试为图片库执行过渡。当图库过渡到下一张幻灯片时,我会将它放在当前幻灯片的左侧,并通过转换其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;
}

因此,默认情况下,我通过将幻灯片向左移动 40 像素来偏移幻灯片(显然我会在此演示之外使用更大的偏移更好地隐藏它们)

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

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

【问题讨论】:

标签: javascript css


【解决方案1】:

就像许多 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';

【讨论】:

  • 欣赏全面的答案。关于为什么它可以在 Firefox 上按预期工作的任何见解?
  • 好吧,我想 Firefox 正在做一个同步布局......或者也许只是他们优化了这种情况,当你想为两个值设置动画时,我不知道。如果 Firefox 总是这样做(同步应用值),那么它大部分时间都是在无用地浪费资源(这将是 Firefox 与 Chrome 相比性能差的一个原因 - 以及与最新版本的 IE 相比的事件)。
猜你喜欢
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
相关资源
最近更新 更多