在 javascript dom 操作后强制在 Internet Explorer 中刷新 DOM

IT技术 javascript internet-explorer dom
2021-02-23 18:19:46

这是情况。我有一些看起来像这样的javascript:

function onSubmit() {
    doSomeStuff();
    someSpan.style.display="block";
    otherSpan.style.display="none";
    return doLongRunningOperation;
}

当我将此作为表单提交操作,并从非 IE 浏览器运行它时,它会快速交换两个跨度的可见性并运行长 javascript 操作。如果我在 IE 中执行此操作,则直到 onSubmit() 完全返回后才会进行交换。

我可以通过像这样粘贴警告框来强制 dom 重绘:

function onSubmit() {
    doSomeStuff();
    someSpan.style.display="block";
    otherSpan.style.display="none";
    alert("refresh forced");
    return doLongRunningOperation;
}

此外,明显的 jquery 重构不会影响 IE 行为:

function onSubmit() {
    doSomeStuff();
    $("#someSpan").show();
    $("#otherSpan").hide();
    return doLongRunningOperation;
}

此行为存在于 IE8 和 IE6 上。无论如何要在这些浏览器中强制重绘 DOM?

6个回答

Mozilla(也可能是 IE)将缓存/延迟对 DOM 执行影响显示的更改,以便它可以一次计算所有更改,而不是在每个语句之后重复计算。

要强制更新(强制立即同步回流或重新布局),您的 javascript 应读取受更改影响的属性,例如 someSpan 和 otherSpan 的位置。

(这个 Mozilla 实现细节在视频Faster HTML and CSS: Layout Engine Internals for Web Developers 中提到。)

非常感谢你!!这救了我。顺便说一句,做视频的人不擅长公开演讲。
2021-04-19 18:19:46
我会在上午试一试。
2021-04-28 18:19:46
我引用Mozilla视频的37:15 时间,他建议要求“顶部偏移”或“左侧偏移”,这要求布局是最新的。
2021-04-29 18:19:46
有趣的。不知道这个。
2021-05-03 18:19:46

继续 ChrisW 所说的:

这是刷新 DOM 的刷新脚本,因此您不必调用 alert(""); (在http://amolnw.wordpress.com/category/programming/javascript/找到):

function flushThis(id){
   var msie = 'Microsoft Internet Explorer';
   var tmp = 0;
   var elementOnShow = document.getElementById(id);
   if (navigator.appName == msie){
      tmp = elementOnShow.parentNode.offsetTop  +  'px';
   }else{
      tmp = elementOnShow.offsetTop;
   }
}

这个对我有用!!! 谢谢你的提示。

我在 Chrome 21 中遇到了这个问题,我在拖动一个带有降序 ('g') 的字母的单词时遇到了这个问题。它在屏幕上留下一串飞蛾灰尘,下次屏幕刷新时它就会消失。ChrisW 的解决方案(询问布局敏感的属性)不起作用。

有效的是在页面顶部添加一个 1 像素的空白 div,然后在一毫秒后通过在拖动操作结束时调用以下函数将其删除:

// Needed by Chrome, as of Release 21. Triggers a screen refresh, removing drag garbage.
function cleanDisplay() {
    var c = document.createElement('div');
    c.innerHTML = 'x';
    c.style.visibility = 'hidden';
    c.style.height = '1px';
    document.body.insertBefore(c, document.body.firstChild);
    window.setTimeout(function() {document.body.removeChild(c)}, 1);
}

注意:您需要延迟。简单地添加和删除是div行不通的。此外,div需要在需要重绘的页面部分上方添加。

这个解决方案是否比像我那样异步调用函数更好?
2021-04-23 18:19:46
在 IE10 中刷新屏幕时出现问题,这与其他方法不同。
2021-04-24 18:19:46
IE8在这里。这是唯一对我有用的解决方案。谢谢。
2021-04-30 18:19:46

您还可以将长期函数包装在 setTimeout(function(){longTerm();},1); 中。

您的 longRunningOperation 可以异步调用吗?

你最终是对的,但需要一些工作。我异步调用了长时间运行的操作,让我的提交事件返回 false,然后异步事件真正提交了我的表单。这导致在所有浏览器中的正确行为,但花费了大量工作并且有点笨拙。
2021-05-01 18:19:46
这可能会让人觉得很笨拙,但您的应用程序客户端的最佳设计将是保持浏览器响应的设计。当您启动长时间运行的进程时,您将挂起浏览器(大不!)所以最好花时间设计如何管理异步操作。无论如何..玩得开心!
2021-05-09 18:19:46