Apple iOS浏览器不会随机渲染动态加载的HTML对象

时间:2019-04-29 12:48:28

标签: javascript ios html5 dom safari

我们有一个问题仅在我们的SPA应用程序的iOS浏览器(iOS 12.0)上可见,该应用程序使用HTML对象标签通过JavaScript将小部件(HTML / CSS / JS文件)加载到页面上。

问题是间歇性的,当页面被加载时,某些小部件没有在屏幕上显示/呈现,而是被加载到DOM中,并且可以在Safari Web Inspector中使用完整元素属性进行查看/突出显示。但对用户“不可见”。如果在页面上加载4个小部件,大约50%的时间会发生此问题,通常不会显示2个,并且每次都不会显示不同的小部件,并且没有可检测的模式。

小部件javascript加载事件正常运行,并且控制台中没有错误。在Safari Web Inspector中,我们可以看到来自非渲染对象的一些HTML元素在位置0,0处加载,但是它们的样式在DOM中是正确的(正确设置了left和top,显示:inline等)。

这是加载窗口小部件的代码(在所有窗口小部件都设置好之后,片段会添加到DOM中):

function loadWidget(myFrag, widgetName) {
    var widgetObj = document.createElement("object");
    widgetObj.data = "widgets/" + widgets[widgetName].type + ".html";        // location of widget
    widgetObj.className = "widget unselectable";
    widgetObj.id = widgetName;
    widgetObj.name = widgetName;
    myFrag.appendChild(widgetObj);                                        // build widgets onto fragment
    widgetObj.addEventListener("load", widgetLoaded, false);            // Run rest of widget initialisation after widget is in DOM
    widgetObj.addEventListener("error", badLoad, true);
}

以下是加载事件中的代码,该代码配置了加载后的小部件(我们解决了一个Chrome错误,该错误也影响到Safari,其中每个加载的对象都会触发两次加载事件):

function widgetLoaded(e) {
    var loadObj = e.target;
    if (loadObj === null) {
        // CHROME BUG: Events fire multiple times and error out early if widget file is missing so not loaded (but this still fires), force timeout
        return;
    }

    var widgetName = loadObj.id;
    // CHROME BUG: Workaround here is to just set the style to absolute so that the event will fire a second time and exit, then second time around run the entire widgetLoaded
    if ((parent.g.isChrome || parent.g.isSafari) && !widgets[widgetName].loaded) {
        widgets[widgetName].loaded = true;                          // CHROME: WidgetLoaded will get run twice due to bug, exit early first time.
        loadObj.setAttribute("style", "position:absolute");         // Force a fake style to get it to fire again (without loading all the other stuff) and run through second time around
        return;
    }

    var defView = loadObj.contentDocument.defaultView;            // Pointer to functions/objects inside widget DOM

    loadObj.setAttribute("style", "position:absolute;overflow:scroll;left:" + myWidget.locX + "px;top:" + myWidget.locY + "px;z-index:" + zIndex);

    loadObj.width = myWidget.scaleX * defView.options.settings.iniWidth;            // Set the width and height of the widget <object> in dashboard DOM
    loadObj.height = myWidget.scaleY * defView.options.settings.iniHeight;
}

该代码在Chrome(Mac / Windows),IE和Safari(Mac)中可以正常运行,但是,在iOS Safari和iOS Chrome中会出现随机的不可见加载问题。

有什么想法会导致这种情况,以及解决方法可能是什么?

1 个答案:

答案 0 :(得分:0)

经过大量调查,我们无法找到此问题的确切来源,并且相当确定这是一个webkit错误。但是,有一种可以接受的解决方法,即用iframe标签替换object标签,并且看起来工作方式完全相同(用.src替换.data),但有一点好处,即在onload时不会显示chrome bug事件触发了两次,因此Chrome现在可以更快地运行我们的应用。