Javascript 为什么CSS转换需要触发回流?

Javascript 为什么CSS转换需要触发回流?,javascript,css,performance,reflow,Javascript,Css,Performance,Reflow,我在读这篇文章,作者写道 “在删除不可见类之前,需要触发回流,以使转换按预期工作。” 我的问题是: 1) 为什么需要触发回流焊 2) 我理解我们应该避免使用回流焊,如果这是真的,那么为什么作者建议使用回流焊来实现过渡 3) 除了使用回流焊,是否有其他方法使过渡工作正常 谢谢。(实际上是:“为什么我不能轻松地将转换与显示属性一起使用呢”) 简短回答: CSS转换依赖于元素的起始或静态属性。当元素设置为显示时:无文档(DOM)被呈现为元素不存在。这意味着当设置为display:block时-没有要转

我在读这篇文章,作者写道

“在删除不可见类之前,需要触发回流,以使转换按预期工作。”

我的问题是:

1) 为什么需要触发回流焊

2) 我理解我们应该避免使用回流焊,如果这是真的,那么为什么作者建议使用回流焊来实现过渡

3) 除了使用回流焊,是否有其他方法使过渡工作正常

谢谢。

(实际上是:“为什么我不能轻松地将转换与
显示
属性一起使用呢”)

简短回答

CSS转换依赖于元素的起始或静态属性。当元素设置为
显示时:无文档(DOM)被呈现为元素不存在。这意味着当设置为
display:block时-没有要转换的起始值

更长的答案

  • 需要触发回流,因为元素设置为
    显示:无尚未在文档中绘制。这将防止转换具有起始值/初始状态。将元素设置为
    显示:无使文档呈现为元素根本不存在
  • 他建议回流,因为人们普遍接受用
    display:none隐藏和显示元素
    显示:块-通常在某个操作(选项卡或按钮单击、回调函数、超时函数等)请求元素之后。过渡对用户体验来说是一个巨大的好处,因此回流是允许这些过渡发生的相对简单的方法。当你在简单的站点上使用简单的转换时,它不会产生巨大的影响,所以一般来说,你可以触发回流,即使从技术上来说你不应该。想想这个家伙的例子,比如在生产站点中使用未统一的JavaScript文件。你能?当然你应该吗?可能不会,但在大多数情况下,这不会产生显著的影响
  • 有不同的选项可用于防止回流,或者通常比您提供的链接中的方法更易于使用。以以下代码段为例:
  • A:此元素设置为
    高度:0
    溢出:隐藏。显示时,设置为
    height:auto。我们仅将动画应用于
    不透明度
    。这给了我们一个类似的效果,但我们可以在不回流的情况下对其进行转换,因为它已经在文档中呈现,并提供了要使用的转换初始值

    B:此元素与A相同,但将高度设置为定义的大小

    A和B在元素淡入时工作得很好,但由于我们立即将高度从
    auto/100px
    设置为
    0
    ,它们似乎在“淡出”时崩溃

    C:此元素被隐藏,我们尝试转换子元素。您可以看到,这也不起作用,需要触发回流

    D:此元素被隐藏,我们为子元素设置动画。由于动画关键帧提供定义的起始值和结束值,因此效果更好。但是请注意,黑框会捕捉到视图中,因为它仍然附着到父对象

    E:这与D的工作原理类似,但我们从孩子身上跑掉了一切,这并不能解决我们与D之间的“黑匣子”问题

    F:这可能是两全其美的解决方案。我们将样式从父对象移到子对象上。我们可以触发父对象的动画,并且可以控制子对象的
    显示
    属性和
    动画
    转换。这样做的缺点是需要使用动画关键帧,而不是过渡

    G:虽然我不知道这是否会触发函数内部的回流,因为我自己还没有对其进行分析,但您可以简单地使用jQuery的
    .fadeToggle()
    函数,用一行JavaScript完成所有这一切,并且经常使用(或类似的JS/jQuery fadeIn/fadeOut方法)回流问题并不经常出现

    示例: 这是一个密码笔:

    下面是一个片段:

    jQuery(文档).ready(函数($){
    $('button:not(#g')。单击(function(){
    $(this).next('div').toggleClass('show');
    });
    $('#g')。单击(函数(){
    $(this).next('div').stop().fadeToggle(2000);
    });
    });
    
    *{框大小:边框框;}
    钮扣{
    文本对齐:居中;
    宽度:400px;
    }
    div{
    边缘顶部:20px;
    背景:#000;
    颜色:#fff;
    }
    A.
    .b{
    溢出:隐藏;
    身高:0;
    不透明度:0;
    过渡:不透明度3s;
    }
    a.表演{
    高度:自动;
    不透明度:1;
    }
    b.表演{
    高度:100px;
    不透明度:1;
    }
    C
    博士{
    显示:无;
    }
    c.show,
    d.表演{
    显示:块;
    }
    c.分区{
    不透明度:0;
    过渡期:3s全部;
    }
    节目组{
    不透明度:1;
    }
    d.分区{
    不透明度:0;
    }
    d.表演部{
    动画:淡入3s;
    }
    @关键帧淡入淡出{
    从{opacity:0;}
    到{opacity:1;}
    }
    e.分区{
    显示:无;
    }
    康乐及文化事务署{
    显示:块;
    动画:淡入3s;
    }
    f{
    背景:透明;
    }
    f.分区{
    背景:#000;
    显示:无;
    }
    节目组{
    显示:块;
    动画:淡入3s;
    }
    g{
    显示:无;
    }
    A:框高度:自动
    这个

    一些奇怪的


    内容
    但是
    这并不重要
    ,因为上面显示,
    我会自动 B:盒子高度:100px 内容为2 C:隐藏-子转换(错误) 内容
    用于
    3
    D:隐藏-子动画(更好) 内容
    用于
    4
    E:隐藏-子对象隐藏并设置动画 内容
    用于
    5
    F:孩子有背景和动画(作品) 内容
    用于
    5
    G:这使用fadeToggle来避免这种情况 我使用
    JavaScript制作动画 我只是显示t底部的页脚