iOS WebView中target="_blank"跳转失效,Articulate课程退出异常求助
iOS WebView中Articulate Rise 360课程的窗口打开与退出问题解决方案
问题描述
- 启动课程窗口问题:点击"start"按钮时,Android及桌面浏览器可通过
window.open在新标签页打开Rise 360课程,但iOS WebView中window.open创建新窗口失败,只能在当前窗口跳转。 - 退出按钮无响应问题:课程内的"EXIT MODULE"按钮默认带有
target="_blank"属性,点击后在iOS中无任何反应;跳转至articulate_close.php后的JS退出逻辑在iOS中失效。
现有代码片段
1. 启动课程的窗口打开逻辑
if (isIOS) { wnd = window.location.href = $(this).data("url"); } else if (isWindows || isAndroid || isSafari || isChrome || isFirefox || isEdge || isOpera) { wnd = window.open($(this).data("url"), 'Captivate Content', 'height=675,width=900,left=100'); } else { wnd = window.open($(this).data("url"), 'Captivate Content', 'height=675,width=900,left=100'); }
2. EXIT MODULE按钮代码
<a class="blocks-button__button brand--ui" href="https://www.getsal.com/articulate_close.php" role="button" tabindex="0" target="_blank" style="background-color: rgb(40, 95, 159);">EXIT MODULE</a>
3. articulate_close.php中的退出逻辑
if (isAndroid ){ window.location.href = 'comprehension.php?activity=' + activityId + '&site=' + site; } else if (isIOS){ window.location.href = 'comprehension.php?activity=' + activityId + '&site=' + site; } else { window.close(); }
解决方案
一、修复iOS下课程启动的新窗口打开问题
iOS WebView对window.open的触发有严格限制,仅允许用户手势直接触发的调用。修改启动逻辑,先创建空窗口再跳转URL,确保符合iOS的安全规则:
if (isIOS) { // 用户点击时触发,先创建空窗口再加载目标URL wnd = window.open('', 'Captivate Content', 'height=675,width=900,left=100'); if (wnd) { wnd.location.href = $(this).data("url"); } else { // 若创建失败,降级为当前窗口跳转 window.location.href = $(this).data("url"); } } else { wnd = window.open($(this).data("url"), 'Captivate Content', 'height=675,width=900,left=100'); }
额外注意:如果使用WKWebView,需在原生代码中配置
allowsLinkPreview = true,并实现WKNavigationDelegate的webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures方法,允许新窗口创建。
二、修复EXIT MODULE按钮的无响应问题
问题根源是target="_blank"会在iOS WebView中打开新窗口,而新窗口无法通过脚本关闭或跳转(iOS限制非脚本创建的窗口的脚本操作)。解决思路是拦截_blank跳转,改为在原窗口处理:
方案1:通过WebView原生代码拦截
若使用WKWebView,在decidePolicyForNavigationAction代理方法中判断跳转目标:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { // 判断是否是target="_blank"的跳转 if navigationAction.targetFrame == nil { // 改为在当前窗口加载URL webView.load(navigationAction.request) decisionHandler(.cancel) return } decisionHandler(.allow) }
方案2:注入JS拦截按钮点击
在Rise 360课程页面加载完成后,注入自定义JS阻止按钮的默认_blank跳转:
// 注入到课程页面的脚本 document.addEventListener('DOMContentLoaded', function() { const exitButton = document.querySelector('.blocks-button__button.brand--ui[href*="articulate_close.php"]'); if (exitButton) { exitButton.addEventListener('click', function(e) { e.preventDefault(); // 阻止默认新窗口跳转 window.location.href = this.href; // 在当前窗口加载退出页面 }); } });
若无法直接修改Rise 360的内容,可通过WebView的
evaluateJavaScript方法在页面加载后注入上述脚本。
三、优化articulate_close.php的退出逻辑
确保iOS下的跳转逻辑能正常触发,可添加强制刷新或替换历史记录:
if (isAndroid || isIOS) { // 替换历史记录,避免用户返回课程页面 window.location.replace('comprehension.php?activity=' + activityId + '&site=' + site); } else { window.close(); }
内容的提问来源于stack exchange,提问作者Hansika Diddugoda
相关产品推荐
相关产品推荐

