Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Having some trouble sorting through the correct approach to handling the load event in Chrome when loading HTML objects.

I'm using HTML objects to load widgets into a web based dashboard and the load event looks to be broken in Chrome, as I get repeat firing of the load event but only if I set the style on the object in the load event to position:absolute. Unfortunately for my application this is a critical feature as I need to place the widget at specific screen locations using javascript.

The fiddle below will put Chrome in an infinite loop while it only fires once in other browsers (although in my app Chrome fires the load event twice then stops).

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

I'm assuming this is a Chrome bug, and although I can work around it by checking how many times the object has been loaded and exit the load event early, there is a performance penalty because it looks like the entire object is reloaded each time (global JavaScript in the object is re-run) and when loading a couple of widgets as objects the browser significantly slows down impacting the end user experience.

No matter what I try I can't seem to avoid the multiple re-loads happening. Has anyone else seen this bug and knows how to avoid the re-loading?

On a related note, Chrome will render and display the object then move it to its correct position which flickers the screen, while other browsers will render the widget at its final location (after the load javascript has been run) which is a nicer experience and I can't find a way to stop Chrome rendering twice.

[Update December '18] - the workaround outlined in the answers below no longer work with the latest version of Chrome (71.0.3578.80) and Chrome is double loading HTML objects and double firing the loaded events. See this Chromium bug post for more info: Chrome bug with HTML Objects

like image 263
deandob Avatar asked Apr 25 '18 09:04

deandob


1 Answers

Not sure about reasons for such behavior in Chrome. However, a workaround seems to be a changing container's style instead of object's style - see fiddle

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

Also after some investigation, I have found that issue probably caused by changing display from inline to block - see fiddle.

like image 82
mykhailo.romaniuk Avatar answered Nov 19 '22 23:11

mykhailo.romaniuk