【问题标题】:UIWebView and unload eventUIWebView 和卸载事件
【发布时间】:2013-07-08 14:45:31
【问题描述】:

我正在将本地 html 内容加载到 UIWebView 中。 加载内容的javascript代码包括这个事件监听器:

window.addEventListener("unload", function(){
  // do something here;
});

该 javascript 代码仅在 UIWebView 组件被释放时(之前)执行(例如,当导航回另一个视图控制器时),但在加载另一个页面时不会执行。例如:

document.addEventListener("click", function(){ document.location = "www.google.com"; });
window.addEventListener("unload", function(){ alert("bye bye"); });

如果在 safari 中执行这段代码,当我点击文档时,在导航到 google.com 之前,它会显示警告框。如果我在 UIWebView 中运行相同的代码,则不会执行卸载侦听器。但是,如果我删除 UIWebView,代码就会被执行。

我的需要是与 Safari 中的相同,即在离开页面时也要执行的卸载方法。

【问题讨论】:

    标签: objective-c uiwebview


    【解决方案1】:

    过去我也遇到过 JavaScript 代码在桌面浏览器中的行为方式与在 UIWebView 中不同的问题。老实说,我不知道为什么它没有按照您想要的方式工作,但在这里我为您提供一个解决方法:

    不要使用 JavaScript 中的 unload 侦听器,而是尝试使用 UIWebViewDelegate 的方法 webView:shouldStartLoadWithRequest:navigationType:。每当用户请求加载新页面(或内容)时,都会调用此方法。 如果你需要执行更多的 JavaScript 代码,你可以使用UIWebView 的方法stringByEvaluatingJavaScriptFromString:

    希望这会有所帮助!

    【讨论】:

    • 您好,根据您的提示,我在 ebView 中执行以下 javascript 代码:shouldStartLoadWithRequest:navigationType, stringByEvaluatingJavaScriptFromString: var e = document.createEvent("Event"); e.initEvent("卸载", true, true); window.dispatchEvent(e);这将触发窗口的卸载侦听器,因此我的 javascript 代码(在加载的 html 页面中)无需修改即可在 UIWebView 和任何其他浏览器中工作
    【解决方案2】:

    感谢上面的 LuisCien 解决方案(如果您喜欢该解决方案,请投票给他的帖子),我设法通过从 Objective-c 端手动生成和调度卸载事件来解决问题。这不需要对我的客户端代码 (javascript) 进行任何修改,这些代码现在在 UIWebView 和任何其他 Web 浏览器中的行为相同。这是要添加到视图控制器的代码:

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        [webView stringByEvaluatingJavaScriptFromString:@"var e=document.createEvent('Event'); e.initEvent('unload', true, true); window.dispatchEvent(e);"];
        return YES;
    }
    

    【讨论】:

    • 嗨@lviggiani。我很高兴你能够解决你的问题。我可以看到您使用了我在回答中建议您的两种方法(不是提示)。您介意将其标记为已接受的答案吗?提前致谢。
    • 嗨 LuisCien,我发布另一个解决方案(即使用您的解决方案)的原因是因为您的解决方案只是我的问题解决方案的一半:您写道“而不是使用您在JavaScript ...”但我必须保持我的 javascript 原样(包括卸载侦听器),因为它也可能在常见的 Web 浏览器中运行。这就是为什么我添加了“服务器端代码”来触发事件,以防其他人想查看如何从 UIWebView 触发该事件。我已经投票给你的答案,并把你的功劳记在我的。
    • 需要注意的一点.. webView:shouldStartLoadWithRequest 如果您在网页中加载 iframe 也会被调用。所以如果你有一个包含多个 iframe 的复杂网页,那么如果你不检查请求的地址,你可能会不必要地抛出这个。
    • 非常感谢。在 WKWebView 实例被关闭后持久化 SAP WebGUI 会话存在问题,因为 SAP WebGUI 使用 window.unload 事件中的代码关闭了 SAP NetWeaver 服务器上的会话(并且未调用)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2017-11-19
    • 2010-12-12
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多