【问题标题】:Toggle CSS transitions on and off with JavaScript使用 JavaScript 打开和关闭 CSS 过渡
【发布时间】:2013-12-02 15:40:30
【问题描述】:

全部,

我遇到了一种情况,我使用 CSS 变换/过渡来为 div 元素的水平位置设置动画。具体来说,我正在使用...

// in CSS
myDiv {
    transition: transform 0.4s ease-in;
}

// in JavaScript, where "div" contains a reference to the div element
div.style.transform = translate3d(Npx, 0px, 0px);

...而且效果很好。也就是说,每次我用 N 的新值调用那行 JavaScript 时,div 都会从当前位置平滑地动画到新位置。

但是,有时我需要先定位 div 而不使用过渡,然后使用过渡移动它。例如,

  1. 让 div 立即跳转到 100 像素,然后过渡(超过 400 毫秒)到 200 像素
  2. 稍后,将 div 跳转到 500px(没有过渡),然后将其过渡到 600px

换句话说,我希望能够移动一个 div,并能够控制新位置是立即应用还是通过过渡应用。

更复杂的是,我有在转换完成时触发的事件监听器;如果/当我在没有过渡的情况下移动 div 时,这些侦听器不应触发。我还支持多种浏览器,所以我必须处理所有供应商前缀。

在伪代码中,我猜它看起来像这样:

  1. 移除 transitionEnd 事件的事件监听器
  2. 将转换属性设置为none
  3. 更改 div 的位置(例如,[div].style.transform = translate3d([starting position]px, 0px, 0px)
  4. 为 transitionEnd 事件添加事件监听器
  5. 将转换属性设置为具有转换(例如,[div].style.transition:all 0.4s ease-in
  6. 更改 div 的位置(例如,[div].style.transform = translate3d([ending position]px, 0px, 0px)

使用所有供应商前缀,这太混乱和复杂,不是实现此目的的最佳方式。 (我什至不确定它是否有效......)

那么,打开和关闭转换/转换的最佳方式是什么?

[更新]

感谢 Chandranshu 的建议,我尝试切换包含转换的类。

所以,我的伪代码如下所示:

  1. 删除转换类
  2. 应用起始位置
  3. 恢复过渡类
  4. 应用结束位置

但是,看起来,如果我在一个 JavaScript 函数中执行所有四个步骤 - 它似乎忽略了步骤 1-2,就好像它正在“净”所有四个步骤的结果。

这是一个演示这个的 jsfiddle:http://jsfiddle.net/bUvX3/

相反 - 如果我执行第 1 步和第 2 步,然后在短暂延迟后执行第 3 步和第 4 步(例如,通过使用 setTimeout),它会起作用:http://jsfiddle.net/2mhcv/

所以,我想这是一个解决方案,除了我真的不喜欢添加任意延迟,尤其是当如此强调快速、响应式 UI 时。

提前致谢!

【问题讨论】:

  • 请检查更新后的答案。您不再需要添加任意延迟。

标签: javascript html css css-transitions css-transforms


【解决方案1】:

我认为您对此过于复杂了 :)。以下是我解决这个问题的方法:

  1. 为您的 div 添加一个类,例如 movable
  2. 声明.movable 的所有转换规则和transitionEnd 回调。
  3. 如果您想顺利移动您的 div,则无需执行任何操作。
  4. 当你需要移动你的 div 没有过渡时,删除这个类,移动你的 div 并添加这个类:$('div').removeClass('movable').animate({transform: 'translate3d(...)' }).addClass('movable')

更新:

最后,我得到了你想要的:http://jsfiddle.net/2mhcv/1/。这里唯一的变化是,我使用的是 0 的延迟,而不是 20 毫秒的延迟! setTimeout() 会触发重绘并确保在下一个动画开始之前执行第一个动画。

更新 2:

此版本无需使用setTimeout() 调用:http://jsfiddle.net/2mhcv/2/。意识到只需要重新绘制,我只是在此处添加了一行来读取计算 CSS 属性,例如 display。您可以读取任何其他计算属性来获得相同的效果。

【讨论】:

  • 这似乎不太奏效。从概念上讲,我需要做四件事:1)删除“可移动”类,2)设置起始位置,3)恢复可移动类,4)设置结束位置(应该过渡)。问题似乎在于,当您在 JavaScript 函数中执行所有四个步骤时 - 它似乎并没有执行所有这些步骤。相反,它“网”出了他们。即,它得出结论,1) 和 3) 的“净”结果是类应该具有“可移动”类,而 2) 和 4) 的净结果是元素应该刚好移动到结束位置。
  • 换句话说,它似乎只是忽略了第 1 步和第 2 步。另一方面 - 如果我执行第 1 步和第 2 步,则创建一个超时,在短时间(200 毫秒)后执行第 3 步和第 4 步延迟 - 它有效。但我不喜欢使用延迟。
  • 我从未见过 Javascript 或 jquery 对连续操作的结果进行净额计算。它们可能发生得如此之快,以至于您无法看到它们。您能否创建一个小提琴,让我可以验证您所看到的内容?
  • Chandranshu - 首先 - 感谢您的帮助。这是我设置的两个小提琴。在这一步中,我在一个函数中执行了所有 4 个步骤:jsfiddle.net/bUvX3 在下一个中,我在 50 毫秒延迟后执行步骤 3 和 4:jsfiddle.net/2mhcv 如您所见,似乎只有具有延迟的那个工作。当然,我可能只是犯了一个愚蠢的错误......
  • 啊,我明白了。你想要的和我建议的有区别,因此我的建议和你实施的有区别。我不想使用转换样式移动 div。我认为 div 被放置在某个容器中,我们知道它当前的左/右位置,我们可以改变它。除非引入故意延迟,否则转换集(尤其是 3d 转换)将一起执行。
猜你喜欢
  • 2014-04-21
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
  • 2014-08-16
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多