javascript - 是否可以通过 Javascript 访问 %-width 元素的当前缩放因子而不会导致回流?

标签 javascript jquery css reflow

我试图在缓慢的 UI 中修复一些性能缓慢的 javascript,我已经将主要原因缩小到 jQuery .width()用于查看 width: 100% 的实际像素大小的调用响应式布局中的元素,在一个需要经常响应用户操作的过程中。

我添加了基于时间戳的测量,它们表明仅它就占了大约 33% 的延迟时间,这使得 UI 感觉清晰和 UI 感觉迟钝之间存在差异。删除这一行,用户界面感觉很快 - 但是,它把东西放在了错误的地方......

好像well established that .width() is relatively slow in jQuery > 1.8主要有两个原因:

  • It forces reflow while calculating the element size .来自 When does reflow happen in a DOM environment? 上引用的一篇文章:

    [ reflow happens when ] you retrieve a measurement that must be calculated, such as accessing offsetWidth, clientHeight, or any computed CSS value (via getComputedStyle() in DOM-compliant browsers or currentStyle in IE)



    ...事实上,对于像 IE 和 Firefox 这样的浏览器,它们会将 DOM 更改延迟到最后一刻以避免发生矛盾的更改(例如,在同一函数调用中隐藏和显示),people sometimes add unnecessary state getters in order to force reflow to occur .
  • 它还需要检查元素的边框状态。 From their blog :

    jQuery 1.8 now needs to check the box-sizing property whenever you use .width() so that it can decide whether it needs to subtract out the padding and border width. That can be expensive—up to 100 times more expensive on Chrome!


  • 我的代码的用途 width()电话是查看响应式设计是否以及缩小了多少。它需要查看一个小部件的包装元素,它有 width: 100%; (但可能在列或其他容器中,具体取决于托管它的站点/页面),并且需要查看它实际显示的包装器最大宽度的百分比。

    基于不同坐标系的其他代码为我提供了标签的位置(以像素为单位),然后我需要使用缩放因子(基本上是 = $wrapper.width() / maxWidth; )来缩小位置,例如,如果页面在狭窄的窗口/设备中查看并且包装器是其最大尺寸的 50%,标签的顶部和左侧偏移是其默认值的 50%。

    有什么方法可以访问这些数据,了解 %-width 元素缩小了多少,而不会导致回流以及其他导致 .width() 的事情。通话慢?

    我尝试或排除的事情:
  • .outerWidth().width() 完全一样慢
  • .get(0).clientWidth (纯 Javascript/非 Jquery 选项)也几乎和 .width() 一样慢(据推测,因此回流是罪魁祸首)
  • 我注意到,在大多数浏览器上,如果我在第一个维度之后执行上述任何一个操作(例如 .get(0).clientWidth 后跟 .outerHeight() ),则调用速度非常快(约快 20 倍)。大概因为回流刚刚完成并且元素属性刚刚被访问,它们以某种方式被缓存。但效果不适用于重复调用该函数,仅在一次函数调用中有效。
  • .css("width")显然没有用,因为它只会给我 100%在所有情况下
  • 我考虑过获取窗口的宽度,但根据托管此元素的页面的列布局,事情会变得复杂。例如,如果我的包装器采用两列布局并且窗口比折叠两列的断点宽一点,则窗口将比包装器元素的最大尺寸宽,但包装器元素不会在其最大宽度的 100%。


  • [ 更新 ] 我想我已经找到了一种方法来绕过解决问题的需要,并在不访问元素缩放的情况下定位我的标签:因为我已经有了 maxWidth以像素为单位的变量和以像素为单位的偏移量,我有足够的数据来计算我的标签的百分比偏移量 leftOffset_px / maxWidth_pxtopOffset_px / maxHeight_px ,然后 + '%'并将其应用为每个标签的 CSS topleft抵消。这速度快得离谱——现在不到 1 毫秒,如此之快,我的基于时间戳的函数无法测量它!

    不幸的是,我还有另一个函数来检查具有固定宽度的标签是否不会溢出响应容器,为此,我确实需要考虑容器的当前像素宽度或其比例因子.

    最佳答案

    不确定这会有多大的改进,但您可以尝试向小部件的根添加一个绝对定位的元素,不包含子元素,其唯一目的是读取其宽度。我认为绝对定位的元素只会重排它的 child :

    .root {
      position: relative;
    }
    .ruler {
      position: absolute;
      width: 100%;
    }
    

    _
    <div class="root>
      ...
      <div class="ruler"></div>
    </div>
    

    ——
    var updatedWidth = $('.ruler').width()
    

    (虽然我同意评论说你应该尝试用 CSS 解决)

    关于javascript - 是否可以通过 Javascript 访问 %-width 元素的当前缩放因子而不会导致回流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39393141/

    相关文章:

    javascript - Rails AJAX 调用无法销毁创建的虚拟记录

    javascript - 使用 node.js Web 服务器写入 Firebase 数据库 - "FIREBASE WARNING: set at ... failed: permission_denied"

    javascript - jquery 选择更改隐藏/显示 div

    javascript - 如何在 jQuery $.get/ajax 请求中获取请求 url

    jquery - 使用 Bootstrap 隐藏元素但保持唯一 ID

    jquery - 大图像 o Masonry 插件

    javascript - 在javascript中用空格替换日期中的字符

    javascript - js Promise - 如果条件满足,如何结束 "then"执行,如果不满足则继续下一步

    javascript - fullcalendar with qtip2 - 如何使 qtip 正确滚动?

    html - CSS 变换 : Scale misaligns overlapping divs