即使在状态更改后激活,也会应用CSS过渡? [英] CSS Transitions applied even if activated after state change?

查看:130
本文介绍了即使在状态更改后激活,也会应用CSS过渡?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个jQuery插件可以在屏幕上移动一个元素,但是有一个animate切换来显示幻灯片的过渡。在尝试使用CSS Transitions而不是Javascript转换进行更改时,我遇到了这个问题,我不确定它是否是一个bug /怪癖,或者我只是做错了:

I have a jQuery plugin that moves an element on the screen, but has an "animate" toggle to show a slide transition or not. In attempting to use CSS Transitions rather than Javascript transitions for the change, I ran across this, and I'm not sure if it's a bug/quirk, or I'm just doing it wrong:

var $item = $('#myItem');
if (!animate) {
  $item.removeClass('csstransitions'); // Class that has "transition:left 0.25s ease-out" 
  $('#myItem').css('left', '300px'); // Move the element
  $('#myItem').addClass('csstransitions'); // Re-apply transitions class
}

这样做时,css会发生变化当转换类未应用于元素但发生后立即应用时,某些浏览器(Chrome和Safari,在我的测试中) 仍然应用CSS转换 ,当根据我的逻辑,它应该只是捕捉到新位置。

When done this way, where the css change happens while the transitions class is not applied to the element, but is applied immediately after, some browsers (Chrome and Safari, in my testing) still apply the CSS transition, when by my logic, it should just snap to the new location.

这个jsFiddle ;在Chrome或Safari中,单击无延迟按钮,并看到它仍然为框的位置设置动画,而延迟按钮(使用超时设置一毫秒后)不会为CSS更改设置动画。

See this in action in this jsFiddle; In Chrome or Safari, click the "No Delay" button, and see that it does still animate the position of the box, while the "Delay" button (which uses a timeout set for one millisecond later) doesn't animate the CSS change.

如jsFiddle所示,我不得不使用setTimeout调用( setTimeout(function(){$ el.addClass(' csstransition');},1); )在Chrome和Safari中获得正确的行为。这只是因为CSS过渡是最前沿的,或者我做错了什么,并且有一种更简单的方法来暂时转变过渡?

As indicated in the jsFiddle, I'm having to use a setTimeout call (setTimeout(function() { $el.addClass('csstransition'); }, 1);) to get the proper behavior in Chrome and Safari. Is this just because CSS transitions are bleeding edge, or am I doing something wrong, and there's a simpler way to temporarily "turn of" the transitions?

编辑:注意到此问题类似的,虽然答案只是将两个调用分开,但问题仍然是为什么我们(Web开发人员)需要将这两个调用分开?这是我们应该用来切换CSS过渡的方法吗?

Noticed this question is similar, and while the answer on that one is to just separate the two calls, the question remains of "why do we (web developers) need to separate those two calls?" Is this the method we should be using to toggle CSS transitions?

推荐答案

我会投票给怪癖或实施差异。

I would vote for quirk, or implementation difference.

在转换之前,应用哪种订单样式并不重要,因为在实际应用中,顺序无关紧要,只是特异性。但是对于过渡,时间延迟的元素被添加到样式中,这是问题的关键。

Before transitions, it really didn't matter which order styles were applied, because in practicality, order didn't matter, just specificity. But with transitions, an element of time delay was added into styles, which is the crux of the issue.

不知道任何浏览器如何应用样式,我猜测Safari和Chrome会做一些优化,不必在每次样式更新后重新流动页面。相反,他们可能会等待特定的时间间隔或事件来进行更新,例如在代码块的末尾。

Not knowing how any of the browsers apply styles, I could guess that Safari and Chrome do some optimizations to not have to re-flow the page after every style update. Instead, they probably wait for particular intervals or events to do the updates, such as at the end of code blocks.

这里将详细介绍一些差异:

http://taligarsiel.com/Projects/howbrowserswork1.htm

Some of the differences are detailed here:
http://taligarsiel.com/Projects/howbrowserswork1.htm

虽然,我不知道是否涵盖了这个特定问题。

Although, I don't know if this specific issue is covered.

作为演示,另一种处理方法是拥有2个点击处理程序:

As demonstration, another way you could handle this is to have 2 click handlers:

$('button#nodelay').on('click', function() {
    var $el = $('#square');
    $el.removeClass('csstransition');
    $el.css('left', '100px');
}).on('click', function() {
    $el.addClass('csstransition');
});

这基本上将两个更新划分为单独的代码块,非常类似于 setTimeout 方法。

This basically divides the two updates into separate code blocks, much like the setTimeout method.

此外,由于转换仍然是草案标准,我不会依赖任何此行为来保持一致,并且怪癖。 (我遇到了一个问题,即转换 top 同时在所有浏览器中都不起作用)。

Also, as transitions are still draft standard, I wouldn't depend on any of this behavior to stay consistent, and there are quirks. (I ran into an issue where transitioning left and top at the same time didn't work in all browsers).

编辑

进一步说明,如果浏览器尽快呈现所有CSS因为它被添加到DOM你得到这个流程:

To further explain, if the browser renders all CSS as soon as it is added to the DOM you get this flow:


  1. CSS left:300px 添加到DOM元素

  2. 样式呈现:浏览器检查元素是否有转换。如果是,则动画,如果不是,立即应用。在这种情况下,不是转换(尚未),因此不会发生动画。

  3. CSS 转换:左2s缓出添加到DOM元素

  4. 样式呈现:无渲染更改,转换适用于未来更改。

  1. CSS left: 300px added to DOM element
  2. Style rendered: Browser checks to see if there is a transition on the element. If so, animate, if not, apply immediately. In this case, there is not a transition (yet), so no animation occurs.
  3. CSS transition: left 2s ease-out added to DOM element
  4. Style rendered: No rendering change, transition applies to future left changes.

但是,如果浏览器优化了CSS的渲染,通过在代码块的末尾(或类似的东西)进行分组,得到这个:

However, if the browser optimizes the rendering of CSS, by grouping at the end of code blocks (or something of the sort), you get this:


  1. CSS left:300px 添加到DOM元素

  2. CSS 转换:左2s缓出添加到DOM元素

  3. 达到渲染点(代码结束)块等),呈现的所有样式:

  4. 当应用 left 时,浏览器会检查是否存在转换元件。如果是,则动画,如果不是,立即应用。在这种情况下,转换,因此动画就会出现。

  1. CSS left: 300px added to DOM element
  2. CSS transition: left 2s ease-out added to DOM element
  3. Rendering point reached (end of code block, etc), all styles rendered:
  4. When left is applied, the browser checks to see if there is a transition on the element. If so, animate, if not, apply immediately. In this case, there is a transition, so the animation occurs.

所以,长度是动画,你等待的时间是无关紧要的。重要的是<* c $ c> left:300px 在应用转换之前呈现。目前,在WebKit中,这意味着在 left 样式的单独的后续代码块中应用过渡样式。这是通过建议的所有答案 setTimeout (具有0延迟的事件),单独的单击处理程序(如果应用第二个)或函数回调来实现的。

So, the length of the animation, and the time you wait is irrelevant. What is important is that the left: 300px gets rendered before the transition is applied. Currently, in WebKit, this means applying the transition style in a separate, later code block than the left style. This is accomplished by all of the answers suggested setTimeout (event with 0 delay), separate click handler (if applied second), or a function callback.

这是另一种方法:

$('button#nodelay').on('click', function() {
    var $el = $('#square');
    $el.removeClass('csstransition');
    $el.css('left', '100px').css('left'); // <-- This (or .show() even)
    $el.addClass('csstransition');
});

这是有效的,因为你强迫浏览器停止并评估CSS,这样你就可以获得值 left (尽管您可以在第二个 .css()调用中放置任何有效的css属性)。在这种情况下,它应用所有CSS并强制元素重新渲染。

This works, because you are forcing the browser to stop and evaluate the CSS so that you can get the value of left (although you could put any valid css attribute in the second .css() call). In this case, it applies all of the CSS and forces the element(s) to re-render.

这篇关于即使在状态更改后激活,也会应用CSS过渡?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆