我遇到了一个问题,这个问题似乎是因为改变了父母中两个<divs>
的位置,基本上是重新排序。
这两个div都应用了transition
css规则:
-webkit-transition: all .2s ease-in-out;
-moz-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
当我打电话给它交换位置时:
function swapElements(first, second) {
$(first).insertBefore(second);
}
first
元素没有浏览器应用的过渡效果,在与上一个/第二个元素交换后,它基本上没有动画效果。
这是一个问题,因为我正在收听转换结束回调,然后在<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
});
}
});
}
由于浏览器没有为此元素进行转换,因此永远不会为此.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function (){});
触发事件<div>
,因此未对其进行初始化。
有没有人对可能导致此行为的原因有任何想法?
修改:Here is a very crude JS fiddle。您需要展开输出窗口,使其为四列。
正如您所看到的,单击前三个中的任何一个都可以获得动画效果,单击标记为<div>
的行中的最后一个LAST ROOM
,不会导致任何动画发生。
有趣的是,如果我将<div>
交换代码包裹在setTimeout
调用中,它可以正常运行,这似乎是一个时间问题,显然我不想依赖于此作为hacky但是,它也会导致div跳到不合适的位置。
答案 0 :(得分:2)
问题出现是因为在交换之后,您还删除了原始类(对于小盒子显示)并替换为新类(对于较大的显示)。这三个都发生在一个阻塞呼叫中。无论何时添加元素,浏览器都需要触发重排,但在每个步骤之后它不会触发重排,因为这样做会影响性能。因此,回流发生在最后(在执行removeClass和addClass之后),因此只有一个元素具有在屏幕上绘制的新类 - 没有状态改变,因此也没有转换。
为了解决这个问题,我们 需要强制UA在交换后但在课程更改之前触发重排/重绘 。这可以用 两种方式 完成 - 一种是强制类更改语句进入不同的函数调用(使用setTimeout
的匿名函数),另一种是通过迫使UA计算像clientHeight
之类的东西(它们强制重绘,因为它们只能计算实际高度)。