Chrome 设置样式位置时对象标签加载多次:绝对

Chrome Object tags load multiple times when setting style position: absolute

在加载 HTML 对象时,在整理 Chrome 中处理加载事件的正确方法时遇到了一些麻烦。

我正在使用 HTML 对象将小部件加载到基于 Web 的仪表板中并且加载事件看起来在 Chrome 中被破坏,因为我重复触发加载事件但前提是我在加载事件中将对象的样式设置为 position:absolute。不幸的是,对于我的应用程序来说,这是一个关键功能,因为我需要使用 javascript 将小部件放置在特定的屏幕位置。

下面的 fiddle 将把 Chrome 置于无限循环中,而它在其他浏览器中只触发一次(尽管在我的应用程序中 Chrome 触发加载事件两次然后停止)。

HTML

<div id="container"></div>
<br/><br/><br/><br/>
<div id="xx">Not Fired..."</div>

JavaScript:

    var cnt = 0;
    (function loadWidget() {
        var widgetObj = document.createElement("object");
        widgetObj.data = ("http://13.75.145.9/widgets/dial.html")                                  // location of widget
        var tt = document.getElementById("container");
        tt.appendChild(widgetObj);
        widgetObj.addEventListener("load", widgetLoaded, false);
    })();

    function widgetLoaded(e) {
        cnt = cnt + 1;
        document.getElementById("xx").innerText = "fired x" + cnt;
    //any manipulation of style is OK, its only the position: absolute that causes re-firing
        e.currentTarget.style = "cursor: move; text-decoration: overline";
        e.currentTarget.style.setProperty("position", "relative");
    // Uncomment out the line below in Chrome and the event will continuously fire, but only once in othe browsers
        e.currentTarget.style = "position: absolute; left: 50px";
    }

Infinite loop

我假设这是一个 Chrome 错误,虽然我可以通过检查对象已加载的次数并提前退出加载事件来解决它,但会降低性能,因为它看起来整个对象每次都重新加载(对象中的全局 JavaScript 重新 运行),并且在将几个小部件作为对象加载时,浏览器会显着减慢影响最终用户体验。

无论我尝试什么,我似乎都无法避免多次重新加载的发生。有没有其他人看到这个错误并且知道如何避免重新加载?

在相关说明中,Chrome 将呈现并显示对象,然后将其移动到正确的位置,这会闪烁屏幕,而其他浏览器将在其最终位置呈现小部件(加载后 javascript 已经 运行) 这是一个更好的体验,我找不到停止 Chrome 渲染两次的方法。

[18 年 12 月更新] - 下面的答案中概述的解决方法不再适用于最新版本的 Chrome (71.0.3578.80) 并且 Chrome 是双重加载 HTML 对象并双重触发加载的事件。有关详细信息,请参阅此 Chromium 错误 post:Chrome bug with HTML Objects

不确定 Chrome 中出现此类行为的原因。但是,解决方法似乎是更改容器的样式而不是对象的样式 - see fiddle

function widgetLoaded(e) {        
    const target = e.currentTarget;        
    target.parentElement.style = "position: absolute; left: 50px;";
 }

此外,经过一些调查,我发现问题可能是由于将 displayinline 更改为 block - see fiddle.