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

Jus*_*ing 28 javascript internet-explorer dom

情况就是这样.我有一些看起来像这样的JavaScript:

function onSubmit() {
    doSomeStuff();
    someSpan.style.display="block";
    otherSpan.style.display="none";
    return doLongRunningOperation;
}
Run Code Online (Sandbox Code Playgroud)

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

我可以通过粘贴一个警告框来强制重绘:

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

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

function onSubmit() {
    doSomeStuff();
    $("#someSpan").show();
    $("#otherSpan").hide();
    return doLongRunningOperation;
}
Run Code Online (Sandbox Code Playgroud)

IE8和IE6上存在此行为.反正是否强制在这些浏览器中重绘DOM?

Chr*_*isW 17

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

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

(这个Mozilla实现细节在视频更快的HTML和CSS:Web开发人员的布局引擎内部中提到.)

  • 在我引用的 **Mozilla** 视频中的 37:15,他建议要求“顶部偏移”或“左侧偏移”,这要求布局是最新的。 (2认同)

小智 9

继续克里斯威说的话:

这里是刷新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;
   }
}
Run Code Online (Sandbox Code Playgroud)

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


Geo*_*rge 5

我在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);
}
Run Code Online (Sandbox Code Playgroud)

注意:您需要延迟.简单地添加和删除div不起作用.此外,div需要在需要重绘的页面部分上方添加.


mis*_*dan 2

您的 longRunningOperation 可以异步调用吗?

  • 你最终是对的,但需要做一些工作。我异步调用长时间运行的操作,让我的提交事件返回 false,然后异步事件真正提交我的表单。这会在所有浏览器中产生正确的行为,但需要做很多工作,而且有点笨拙。 (2认同)