未附加到视图层次结构时的WKWebKit JavaScript执行

2020/12/16 19:51 · ios ·  · 0评论

我想切换到WKWebViewUIWebView在我的代码中,在屏幕外(不附加到视图层次结构)创建了Web视图实例,并加载了URL。加载完成后,网络视图会在单独的UIWindow(如插页式广告)中呈现给用户。一切正常UIWebView; 但是切换到后WKWebView,有角度的javascript代码会以意外的方式运行。

经过研究后,我发现当WKWebView实例未附加到视图层次结构时,javascript计时器(和HTTP加载程序)将被挂起:如果您在以detached形式运行的javascript中启动计时器,则该计时器WKWebView不会被触发Web视图已附加。

任何人都可以提出一种可能的解决方法(将隐藏的Web视图附加到关键窗口,然后再将其移动到另一个窗口)吗?

我创建了一个示例项目来演示该问题(或更可能是WebKit功能)

https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.zip

测试应用程序使用javascript加载网页,以计划计时器并加载HTTP请求。您可以使用开关来显示/隐藏Web视图(设置为“隐藏”属性),并将其从视图层次结构附加/分离。

在iOS 8.0上运行的示例应用

如果附加了网络视图(隐藏或可见),然后单击Load,则javascript可以正常工作:您可以看到successfailure警告对话框。如果它是分离的,则计时器仅在连接到视图层次结构时才会触发(将“已分离”切换为“打开”,单击“加载”,等待几秒钟,然后再切换回“关闭”)。您也可以console.log从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:

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将其移出屏幕外,我再也找不到任何解决方案。幸运的是,此替代方法确实可以可靠地工作。

我有完全相同的问题,并已通过解决UIStackView我为创建了StackNavigationController,最低限度的直接替换UINavigationController,基本上将新视图添加到堆栈中,同时隐藏了除最后一个视图以外的所有视图。因此,所有视图仍处于层次结构中,正在执行和加载,但是只有最后一个可见。没有动画,缺少很多API,可以随意构建。

public class StackNavigationController: UIViewController {

    private(set) var viewControllers: [UIViewController] = []
    private var stackView: UIStackView { return view as! UIStackView }

    override public func loadView() {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        view = stackView
    }

    func pushViewController(_ viewController: UIViewController, animated: Bool) {
        let previousView = stackView.arrangedSubviews.last
        viewControllers.append(viewController)
        stackView.addArrangedSubview(viewController.view)
        previousView?.isHidden = true
    }

    func popToRootViewController(animated: Bool) {
        while stackView.arrangedSubviews.count > 1 {
            stackView.arrangedSubviews.last?.removeFromSuperview()
            viewControllers.removeLast()
        }
        stackView.arrangedSubviews.first?.isHidden = false
    }

}

我的故事:

  1. 我有一个UINavigationControllerWKWebView(1)作为根视图
  2. WKWebView(1)具有target: _blank参数集的超链接
  3. 轻敲链接后,我抓住WKUIDelegatewebView(_:didRequestNewWebView:),并推动另一个WKWebView(2)UINavigationController
  4. WKWebView(2) 向服务器执行请求
  5. 服务器以JavaScript消息响应 WKWebView(1)
  6. 我永远都不会收到消息,因为WKWebView(1)已停止
本文地址:http://ios.askforanswer.com/weifujiadaoshitucengcijiegoushidewkwebkit-javascriptzhixing.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!