我可以使用javascript强制浏览器“刷新”吗?任何挂起的布局更改

Can I use javascript to force the browser to "flush" any pending layout changes?

本文关键字:任何 挂起 布局 刷新 javascript 可以使 浏览器 我可以      更新时间:2023-09-26

我有一个使用Javascript构建UI的库,由于涉及到动态内容,我有时想把内容放到浏览器中,检查如何改变布局以支持这一点,然后根据结果执行不同的逻辑。例如:检测某些文本是否溢出并使用省略号截断。

通常我通过放置更改来实现这一点,然后使用window.setTimeout(0)等待布局更新并调用其余的逻辑。这显然是次优的,因为不同的浏览器可能会实现一个最小的超时,太慢而无法防止闪烁,或者更快,使用大量的CPU。

理想情况下,我想做DOM更改,然后强制布局同步更新,并立即内联运行"修复"逻辑。什么好主意吗?

我的理解是读取任何CSS属性都会强制流。您根本不需要setTimeout

节选自渲染:重新绘制,回流/布局,重新设计:

但有时脚本可能会阻止浏览器优化回流,并导致它刷新队列并执行所有批处理更改。当您请求样式信息时,例如

,就会发生这种情况。
 offsetTop, offsetLeft, offsetWidth, offsetHeight
 scrollTop/Left/Width/Height
 clientTop/Left/Width/Height
 getComputedStyle(), or currentStyle in IE

以上所有这些本质上都是请求一个节点的样式信息,任何时候你这样做,浏览器必须给你最新的值。为了做到这一点,它需要应用所有计划的更改,刷新队列,咬紧牙关并执行流。

下面是触发流的API调用/属性列表。

(这个答案曾经链接到一个网站,现在404。

我们在IE8上遇到了一个疯狂的问题(Firefox和Chrome都还好)。我们在子元素上使用toggleClass('enoMyAddressesHide')

.enoMyAddressesHide{display:none}

但是父div容器不会刷新/重新布局它的高度。

setTimeout(),读取位置,读取宽度和高度的元素没有帮助。最后我们可以找到一个可行的解决方案:

jQuery(document).ready(function ($) {
    var RefreshIE8Layout = function () {
        $('.enoAddressBook:first').css('height', 'auto');
        var height = $('.enoAddressBook:first').height();
        $('.enoAddressBook:first').css('height', height);
    };
    $(".enoRowAddressInfo .enoRowAddressInfoArea ul li img.enoMyAddresses").click(function () {
        $(this).parent().find(".enoAllInfoInAddressBox,img.enoMyAddresses").toggleClass('enoMyAddressesHide');
        RefreshIE8Layout(); // fix IE8 bug, not refresh the DOM dimension after using jQuery to manipulate DOM
    });
});

看起来很蠢,但是很有效!

我不知道这实际上会为您的实现工作,但是:

var myDiv = document.getElementById("myDiv");
myDiv.innerHTML = "".concat(myDiv.innerHTML);

我认为设置innerHTML会强制为子元素重新加载DOM。我不知道如果你把这个范围扩大到整个网站会发生什么。听起来好像您已经完全与DOM连接在一起了,而且这个方法可能会使您已经创建的任何节点引用变为未定义的。换句话说:

var mySelect = document.getElementById("mySelect");// suppose this lives in myDiv.
var myDiv = document.getElementById("myDiv");
myDiv.innerHTML = "".concat(myDiv.innerHTML);

在上面的例子中,我相信你会丢失对mySelect的引用。如果你有很多这样的操作,并且你使用的是字段而不是getter(也就是说,不是每次访问时都使用$()或$get或document.getElementById(..)来获取你关心的每个元素),那么这种类型的刷新很有可能会让你失败。

你也肯定会丢失任何你没有手动跟踪/设置的页面状态数据——带有用户新文本的文本框,用户新选中的复选框,等等,使用这种刷新方法将重新初始化为默认状态。

祝你好运-快乐编码!

B

你可以!!

大多数浏览器通过排队更改和批量执行来优化回流过程。刷新呈现树的变化需要您检索一些布局信息(偏移量计算、getComputedStyle()和滚动值)。

var el = document.getElementById("my-element");
var top = el.offsetTop;

以上代码将强制浏览器在呈现队列中执行更改,以便返回正确的值。

简单! !