美文网首页
[css] smooth-dnd拖拽异常背后的知识

[css] smooth-dnd拖拽异常背后的知识

作者: alue | 来源:发表于2022-05-01 15:27 被阅读0次

    css

    项目中用了 smooth-dnd 这个拖拽组件。其优势是使用css实现拖动动画,这样能够有效的利用硬件加速,用起来比较丝滑。

    但是遇到一个什么坑呢?

    一旦我在它的父辈节点加入quasar组件 QScrollArea,节点拖动的位置就发生了位移。

    这就要去研究这里面的原理了。

    节点被拖动,肯定是监听了鼠标设备的位置,然后将鼠标位置赋予被拖动的元素。

    查看 smooth-dnd 组件,发现它的拖动位置是靠css 的 fixed 定位实现的。

    很明显,这里定位出错了。

    对比加入 QScrollArea 组件前后的fixed位置,发现二者相同,那么问题只剩下坐标基准的选择问题了。也就是说,fixed的定位,究竟是相对于谁来做的

    大多数情况下,fixed定位都是相对屏幕视口(viewport)来说的,MDN上说,有三种情况fixed定位会变化:

    当元素祖先的 transform, perspective 或 filter 属性非 none 时,容器由视口改为该祖先。

    于是我自信的去查找 QScrollArea 组件的 transform, perspective 或 filter 属性,遗憾的是,这三个属性都是none。那是什么问题呢?难倒MDN都不可靠吗?

    正一筹莫展之际,发现 QScrollArea 组件css中有个不常见的属性:contain: strict .

    抱着试试看的心态把它关掉后,发现拖拽正常了!

    那么,这个属性是做什么的呢?

    还得求助MDN:

    The contain css property allows an author to indicate that an element and its contents are, as much as possible, independent of the rest of the document tree. This allows the browser to recalculate layout, style, paint, size, or any combination of them for a limited area of the DOM and not the entire page, leading to obvious performance benefits.
    This property is useful on pages that contain a lot of widgets that are all independent, as it can be used to prevent each widget's internals from having side effects outside of the widget's bounding-box.

    原来,这个属性是做性能优化的。如果认为当前节点的所有子元素都与页面其它元素无关的话,就可以使用这个属性,这样浏览器再做渲染时,能够减少计算量,有点像上一篇日更里提到的“局部渲染”。

    这下总算结案了:QScrollArea 组件为了提高性能,加入的contain属性,却意外的破坏了smooth-dnd 组件的定位机制。

    解决办法也很简单,让contain属性置为none即可。

    相关文章

      网友评论

          本文标题:[css] smooth-dnd拖拽异常背后的知识

          本文链接:https://www.haomeiwen.com/subject/qpkpyrtx.html