WKWebKit未附加到视图层次结构时执行javascript [英] WKWebKit javascript execution when not attached to a view hierarchy
问题描述
我想从 UIWebView
切换到 WKWebView
。在我的代码中,Web视图实例是在屏幕外创建的(不附加到视图层次结构)并且加载了URL。加载完成后,Web视图将在单独的UIWindow(如插页式广告)中呈现给用户。使用 UIWebView
,一切正常;但是在切换到 WKWebView
之后,角度javascript代码以一种意想不到的方式运行。
I want to switch to WKWebView
from UIWebView
. In my code, the web view instance is created offscreen (without attaching to the view hierarchy) and URL is loaded. When loading is done, the web view is presented to the user in a separate UIWindow (like an interstitial ad). Everything works fine with UIWebView
; but after switching to WKWebView
, the angular javascript code behaves in an unexpected way.
在做了一些研究后,我当 WKWebView
实例没有附加到视图层次结构时,我们发现javascript计时器(和HTTP加载器)被暂停:如果你在javascript中启动一个以分离运行的计时器 WKWebView
- 在附加Web视图之前不会触发它。
After doing some research, I've figured out that javascript timers (and HTTP loaders) are suspended when the WKWebView
instance is not attached to the view hierarchy: if you start a timer in javascript which runs in detached WKWebView
- it won't be fired until the web view is attached.
任何人都可以建议可能的解决方法(除了将隐藏的Web视图附加到关键窗口然后将其移动到另一个窗口)?
Can anyone suggest a possible workaround (besides attaching a hidden web view to the key window and then moving it to another window)?
我已经创建了一个示例项目来演示该问题(或者更可能,一个WebKit功能)
I've created a sample project to demonstrate the issue (or, more likely, a WebKit feature)
https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.zip
测试应用程序加载一个带有javascript的网页,用于安排计时器和加载HT TP请求。您可以使用开关来显示/隐藏Web视图(设置'隐藏'属性)并将其从视图层次结构中附加/分离。
The test application loads a web page with javascript which schedules a timer and loads HTTP request. You can use switches to show/hide web view (sets 'hidden' property) and attach/detach it from the view hierarchy.
如果附加了Web视图(隐藏或可见)并且你点击加载
,javascript工作正常:你可以看到成功
或失败
警告对话框。如果它已经分离 - 计时器只会在它附加到视图层次结构时触发(将Detached切换为on,点击Load,等待几秒钟并切换回off)。您还可以从Safari Web Inspector中检查 console.log
。
If the web view is attached (hidden or visible) and you hit Load
, the javascript works fine: you can see success
or failure
alert dialog. If it's detached - the timer will only fire when it's attached to the view hierarchy (switch "Detached" to "on", hit "Load", wait a couple of seconds and switch back to "off"). You can also check console.log
from Safari Web Inspector.
以下是测试网页来源:
<!doctype html>
<html ng-app="project">
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="project.js"></script>
</head>
<body>
<div id="simple" ng-controller="MyController" data-ng-init="callNotify(message);">
</div>
</body>
</html>
javascript:
And the javascript:
angular.
module('project', []).
controller('MyController', ['$scope','notify', function ($scope, notify) {
$scope.callNotify = function(msg) {
notify(msg);
};
}]).
factory('notify', ['$window', '$http', '$q', '$timeout', function(win, $http, $q, $timeout) {
return function(msg) {
deferred = $q.defer();
$timeout(function() {
$http.get('http://jsonplaceholder.typicode.com/posts').
success(function(data, status, headers, config) {
alert("success");
console.log("success")
}).
error(function(data, status, headers, config) {
alert("error");
console.log("error")
});
});
return deferred.promise;
};
}]);
推荐答案
遇到同样的问题,我从未发现任何问题除了将WKWebView添加到视图层次结构并使用AutoLayout将其移出屏幕外的解决方案。幸运的是,这种解决方法确实可靠。
Having run into the same problem, I never found any solution except to add the WKWebView to the view hierarchy and move it offscreen with AutoLayout. Fortunately, this workaround does work reliably.
这篇关于WKWebKit未附加到视图层次结构时执行javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!