简体   繁体   English

交换 <div> 位置导致CSS3过渡效果丢失

[英]Swapping <div> position causes loss of CSS3 transition effect

I've got an issue which seems to be caused by altering the position of two <divs> within their parent, essentially re-ordering them. 我有一个问题似乎是由于改变了父级中两个<divs>的位置,实质上是重新排序它们。

Both divs have a transition css rule applied like so: 这两个div都有一个transition css规则,如下所示:

-webkit-transition: all .2s ease-in-out;
-moz-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;

When I call this to swap the position: 当我打电话给这个职位时:

function swapElements(first, second) {
    $(first).insertBefore(second);
}

The first element is not having the transition effect applied by the browser, it essentially doesn't animate at all after having been swapped with the previous/second element. first元素没有浏览器应用的过渡效果,它在与上一个/第二个元素交换后基本上没有动画。

This is a problem as I'm listening to the transition end callback to then do some more work within the <div> (initializing a gallery): 这是一个问题,因为我正在收听转换结束回调,然后在<div> (初始化图库)中做更多的工作:

if (Modernizr.csstransitions) {
        $(roomColumn).one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function () {
           if (!gallery.hasClass('slick-initialized')) {
                $(gallery).slick({
                    lazyLoad: 'progressive',
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    autoplay: false,
                    dots: false,
                    adaptiveHeight: false
                });
            }
        });
    }

Because the browser isn't doing the transition for this element, the event .one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function (){}); 因为浏览器没有为这个元素做过渡,所以事件.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function (){}); is never fired for this <div> and so the gallery is not initialized for it. 永远不会为此<div>触发,因此库未初始化。

Does anyone have any ideas on what could be causing this behaviour? 有没有人对可能导致这种行为的原因有任何想法?

Edit: Here is a very crude JS fiddle . 编辑: 这是一个非常粗鲁的JS小提琴 You will need to expand the output window so that are four columns. 您需要展开输出窗口,使其为四列。

As you can see, clicking any of the first three gives you an animation effect, clicking the last <div> in the row, labelled LAST ROOM , does not cause any animation to occur. 如您所见,单击前三个中的任何一个为您提供动画效果,单击行中标记为LAST ROOM的最后一个<div>不会导致任何动画发生。

Interestingly, if I wrap the <div> swapping code in a setTimeout call it works fine, it seems like a timing issue, obviously I don't want to rely on this as a hacky fix though, it also causes the div to jump into place which is undesirable. 有趣的是,如果我在一个setTimeout调用中包装<div>交换代码它工作正常,这似乎是一个计时问题,显然我不想依赖它作为一个hacky修复,但它也导致div跳进这是不受欢迎的地方。

The problem happens because after swapping, you are also removing the original classes (for the small box display) and replacing with the new ones (for the larger display). 出现问题的原因是交换后,您还要删除原始类(对于小框显示)并替换为新类(对于较大的显示)。 All three happen within a single blocking call. 这三个都发生在一个阻塞呼叫中。 Whenever an element is added, the browser would need to trigger a reflow but it doesn't trigger the reflow after each step as doing so will affect performance. 无论何时添加元素,浏览器都需要触发重排,但在每个步骤后都不会触发重排,因为这样做会影响性能。 So, the reflow happens at the end (after execution of the removeClass and addClass also) and thus there is only an element with new classes which is being painted on the screen - no state change and so no transition also. 因此,回流发生在最后(在执行removeClass和addClass之后),因此只有一个元素具有在屏幕上绘制的新类 - 没有状态改变,因此也没有转换。

To overcome this, we need to force the UA to trigger a reflow/repaint after swapping but before the class changes . 为了解决这个问题,我们需要强制UA在交换之后但在类更改之前触发重排/重绘 This can be done in two ways - one is to force the class change statements into a different function call (anonymous function using setTimeout ) and the other is by forcing the UA to calculate things like clientHeight etc (they force a repaint because they can only then calculate the actual height). 这可以通过两种方式完成 - 一种是强制类更改语句进入不同的函数调用(使用setTimeout匿名函数),另一种是强制UA计算像clientHeight等的东西(它们强制重绘,因为它们只能然后计算实际高度)。

Demo with setTimeout | 使用setTimeout进行演示 | Demo with clientHeight 使用clientHeight进行演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM