首页 > 解决方案 > 设置样式位置时,Chrome Object 标签会多次加载:absolute

问题描述

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

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

下面的小提琴将使 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";
    }

无限循环

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

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

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

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

标签: javascriptgoogle-chromedom-eventshtml-object

解决方案


不确定 Chrome 中这种行为的原因。然而,一种解决方法似乎是改变容器的风格而不是对象的风格 -见小提琴

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

同样经过一番调查,我发现这个问题可能是由于displayinlineto block- see fiddle改变引起的。


推荐阅读