Apple iOS浏览器不会随机渲染动态加载的HTML对象 [英] Apple iOS browsers randomly won't render HTML objects loaded dynamically

查看:70
本文介绍了Apple iOS浏览器不会随机渲染动态加载的HTML对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a problem that is only evident on iOS browsers (iOS 12.0) with our SPA application that uses HTML object tags to load widgets (HTML/CSS/JS files) through JavaScript onto the page.

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

The issue is an intermittent one when the page is loaded some of the widgets don't display/render on the screen, yet are loaded into the DOM and can be viewed/highlighted with full element properties in the Safari Web Inspector. but are "invisible" to their user. The problem will occur about 50% of the time if there are 4 widgets to load on a page, 2 typically won't display and it will be different widgets not displaying each time, with no detectable pattern.

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

The widget javascript load events run properly and there are no errors in the console. In the Safari Web Inspector, we can see some of the HTML elements from the non-rendering object are loaded at position 0,0 but their style is correct in the DOM (left and top set correctly, display: inline, etc.).

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

Here is the code that loads the widgets (the fragment is added to the DOM after all widgets are setup):

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,对于每个加载的对象,该加载事件都会触发两次):

Here is the code in the load event that configures the widget once loaded (we work around a Chrome bug that also affects Safari where the load event is fired twice for every object loaded):

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中会出现随机的不可见加载问题.

The code performs correctly in Chrome (Mac/Windows), IE and Safari (Mac), however, presents the random invisible loading issue in iOS Safari and also in iOS Chrome.

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

Any ideas what causes this and what the workaround could be?

推荐答案

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

We couldn't find the exact source of this issue after a lot of investigation and are fairly sure this is a webkit bug. However there is an acceptable workaround, which is to replace the object tag with an iframe tag, and it looks to be working exactly the same way (replace .data with .src) with a bonus it doesn't exhibit the chrome bug where onload events are fired twice, so Chrome runs our app faster now.

这篇关于Apple iOS浏览器不会随机渲染动态加载的HTML对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆