【问题标题】:Forcing a DOM refresh in Internet explorer after javascript dom manipulationjavascript dom 操作后在 Internet Explorer 中强制刷新 DOM
【发布时间】:2010-11-26 17:12:26
【问题描述】:

情况是这样的。我有一些看起来像这样的 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 的方法?

【问题讨论】:

  • 首先,你在 longRunningOperation 中做什么?
  • 您是否尝试过将可见性切换移动到它自己的功能?
  • longRunningOperation 正在进行表单验证。在一小部分情况下,表格很大。

标签: javascript internet-explorer dom


【解决方案1】:

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

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

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

【讨论】:

  • 有趣。不知道这个。
  • 我会在上午试一试。
  • 在我引用的 Mozilla 视频中的 37:15 时,他建议要求“上偏移”或“左偏移”,这要求布局是最新的日期。
  • 非常感谢!!这救了我。顺便说一句,做视频的人很不擅长公开演讲。
【解决方案2】:

继续 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;
   }
}

它对我有用!!! 感谢您的提示。

【讨论】:

    【解决方案3】:

    我在 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 需要添加到需要重绘的页面部分上方。

    【讨论】:

    • 这个解决方案比像我那样异步调用函数更好吗?
    • 在 IE10 中出现屏幕刷新问题,这与其他问题不同。
    • 这里是 IE8。这是唯一对我有用的解决方案。谢谢。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      你的 longRunningOperation 可以异步调用吗?

      【讨论】:

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

      element.focus() 在 IE10 中为我工作

      function displayOnOff(){
          var elm = document.getElementById("myDiv");
          elm.style.display="block";
          elm.focus();
          for(var i=0; i<1000000; i++){
              console.log("waiting...............");
          }
          elm.style.display = "none";
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-23
        相关资源
        最近更新 更多