UIWebView和unload事件

5
我将本地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相同,即在从页面导航离开时也执行卸载方法。

2个回答

5
我过去也遇到过 JavaScript 代码在桌面浏览器和 UIWebView 中表现不同的问题。我不知道为什么它不能按照您期望的方式工作,但是我这里提供一个解决方法:
不要使用 JavaScript 中的 unload 监听器,而是尝试使用 UIWebViewDelegate 的方法 webView:shouldStartLoadWithRequest:navigationType:。每当用户请求加载新页面(或内容)时,都会调用此方法。如果您需要执行更多 JavaScript 代码,则可以使用 UIWebView 的方法 stringByEvaluatingJavaScriptFromString:
希望这有所帮助!

你好,根据你的提示,我在ebView:shouldStartLoadWithRequest:navigationType, stringByEvaluatingJavaScriptFromString中执行了以下javascript代码:var e = document.createEvent("Event"); e.initEvent("unload", true, true); window.dispatchEvent(e);这将触发窗口的卸载监听器,因此我的javascript代码(在加载的html页面中)将在UIWebView和任何其他浏览器中工作,而无需进行修改。 - lviggiani

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
嗨,LuisCien,我发布另一个解决方案(使用您的解决方案)的原因是因为您的解决方案只是我的问题的一半:您写道“不要使用JavaScript中的卸载侦听器……”,但我必须保持我的javascript不变(包括卸载侦听器),因为它可能在普通的Web浏览器中运行。这就是为什么我添加了“服务器端代码”来触发事件,以防其他人想要查看如何从UIWebView触发该事件。我已经投票支持您的答案,并在我的答案中给予了您的荣誉。 - lviggiani
需要注意的一点是,如果您在网页中加载了一个iframe,则也会调用webView:shouldStartLoadWithRequest方法。因此,如果您的网页非常复杂,包含多个iframe,则如果不检查请求的地址,可能会引发不必要的问题。 - JDL
非常感谢。在WKWebView实例被解除后,持久化SAP WebGUI会话存在问题,因为SAP WebGUI使用window.unload事件中的代码关闭SAP NetWeaver服务器上的会话(但此事件未被调用)。 - Manfred Scheiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接