是否有可能通过Javascript访问%-width元素的当前缩放因子而不会引起流?



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

我添加了基于时间戳的测量,它们显示仅它就占了大约33%的延迟时间,这使得UI感觉敏锐和UI感觉迟钝之间的差异。删除这一行,UI感觉很快-但是,它把东西放在错误的地方…

.width()在jQuery> 1.8中相对较慢,这似乎是公认的,主要有两个原因:

  • 在计算元素大小时强制回流。从一篇文章引用何时回流发生在DOM环境?:

    [回流发生时]你检索测量必须计算,如访问offsetWidth, clientHeight,或任何计算的CSS值(通过getComputedStyle()在dom兼容的浏览器或currentStyle在IE)

    …事实上,对于像IE和Firefox这样的浏览器,延迟DOM更改直到最后一刻,以避免相互矛盾的更改(例如,在同一个函数调用中隐藏和显示),人们有时会添加不必要的状态getter,以便强制回流发生。

  • 它还需要检查元素的边框状态。来自他们的博客:

    jQuery 1.8现在需要在使用。width()时检查box-sizing属性,以便它可以决定是否需要减去填充和边框宽度。这可能会很昂贵——在Chrome上要贵100倍!

我代码的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%。

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

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

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

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

_

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

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

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

最新更新