我们有一个问题仅在我们的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中会出现随机的不可见加载问题。
有什么想法会导致这种情况,以及解决方法可能是什么?
答案 0 :(得分:0)
经过大量调查,我们无法找到此问题的确切来源,并且相当确定这是一个webkit错误。但是,有一种可以接受的解决方法,即用iframe标签替换object标签,并且看起来工作方式完全相同(用.src替换.data),但有一点好处,即在onload时不会显示chrome bug事件触发了两次,因此Chrome现在可以更快地运行我们的应用。