如何在Cordova的InAppBrowser中优雅地中断加载某个URL并在系统浏览器中打开它?
How do I gracefully interrupt loading of a certain URL in Cordova's InAppBrowser and open it in the system browser?
我正在使用 Cordova 的 inappbrowser 插件在我的应用程序中显示 Web 部件。在网站上,有分享 links,例如对于 WhatsApp:
<a href="whatsapp://send?text=Check this out">Share on WhatsApp</a>
现在,当在 inappbrowser 中单击这些 link 时,它只是尝试将 whatsapp://send?...
作为 URL 加载并显示错误页面。
我想做的是使用给定系统的 browser/URI 处理程序打开以 whatsapp://
开头的 links,因此它类似于单击此类 link 时的行为在系统的浏览器中。为此,我执行了以下操作:
urlChanged = function(event) {
// when a "whatsapp://" link is clicked, open it in the system browser
if(event.url.startsWith("whatsapp://")) {
window.open(event.url, "_system");
return;
}
}
// Add an "loadstart" event listener to the inappbrowser:
browser.addEventListener("loadstart", urlChanged);
到目前为止,这有点奏效,但有一些怪癖:
- 虽然当用户单击 WhatsApp link 时事件会立即触发(通过触发警报进行检查),但系统浏览器实际打开需要大约两三秒钟的时间。
- 在等待这 2-3 秒并返回到应用程序时,用户会看到一个 inappbrowser 错误页面,提示
whatsapp://
link 无法打开 ("unknown url scheme")。
为了缓解第 2 点,我还在事件侦听器中尝试了以下操作,但没有成功(行为完全相同):
urlChanged = function(event) {
if(event.url.startsWith("whatsapp://")) {
// stop loading the whatsapp:// link in inappbrowser
browser.stop();
// go back in history to display page where whatsapp:// link was on
browser.history.back();
window.open(event.url, "_system");
return;
}
}
browser.addEventListener("loadstart", urlChanged);
你能指导我如何解决第 1 点和第 2 点吗?
所以我得到了以下代码:
openWithSystemBrowser = function(url) {
window.open(url, "_system");
location.href = "index.html";
};
shareOnWhatsapp = function(url) {
openWithSystemBrowser(url);
};
/**
* Handles URL changes in in-app browser, e.g. to handle logouts or
* unsuccessful logins
*/
urlChanged = function(event) {
if(event.url.startsWith("http://whatsapp://")) {
shareOnWhatsapp(event.url.substr("http://".length));
return;
}
if(event.url.startsWith("whatsapp://")) {
shareOnWhatsapp(event.url);
return;
}
};
这当然有点蹩脚,因为你总是被带回 index.html,但就我的目的而言,这已经足够了。有兴趣看看是否有人找到了更优雅的解决方案。
它也解决了打开系统浏览器之前的2-3秒延迟,但我不知道为什么,坦率地说。
我找到了一个用户体验更好的方法:在系统浏览器中加载外部URL时,我关闭InAppBrowser并用最后一个内部URL重新打开它。
var appUrl = 'https://www.my-website.com';
var app = {
currentUrl: appUrl,
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
onDeviceReady: function() {
app.openBrowser();
},
openBrowser: function() {
var target = '_blank';
var options = [
"location=no",
"clearcache=no",
"clearsessioncache=no",
"footer=no",
"hardwareback=no",
"hideurlbar=yes",
"zoom=no",
"hidenavigationbuttons=no",
"toolbar=yes",
"hidespinner=yes",
"toolbarcolor=#000000",
"toolbartranslucent=no",
"navigationbuttoncolor=#ffffff",
"closebuttoncolor=#000000",
"closebuttoncaption="
];
browser = cordova.InAppBrowser.open(app.currentUrl, target, options.join());
// reopen the browser if it was closed via "Done" button
browser.addEventListener('exit', function(){ app.openBrowser(); } );
// open external urls in system browser window
browser.addEventListener('loadstart', function(event){ app.handleUrl(event.url, browser); });
},
handleUrl: function(url, browser) {
var extension = url.split('.').pop();
// load internal urls that are not pdf files in the app browser
if (extension != 'pdf' && url.startsWith(appUrl)) {
app.currentUrl = url;
return;
}
// open website in system browser window
var ref = cordova.InAppBrowser.open(url, '_system', 'location=no');
// since the inapp browser is loading the website too, close it and open it again with the last internal url visited
browser.close();
app.openBrowser();
return;
}
};
app.initialize();
我正在使用 Cordova 的 inappbrowser 插件在我的应用程序中显示 Web 部件。在网站上,有分享 links,例如对于 WhatsApp:
<a href="whatsapp://send?text=Check this out">Share on WhatsApp</a>
现在,当在 inappbrowser 中单击这些 link 时,它只是尝试将 whatsapp://send?...
作为 URL 加载并显示错误页面。
我想做的是使用给定系统的 browser/URI 处理程序打开以 whatsapp://
开头的 links,因此它类似于单击此类 link 时的行为在系统的浏览器中。为此,我执行了以下操作:
urlChanged = function(event) {
// when a "whatsapp://" link is clicked, open it in the system browser
if(event.url.startsWith("whatsapp://")) {
window.open(event.url, "_system");
return;
}
}
// Add an "loadstart" event listener to the inappbrowser:
browser.addEventListener("loadstart", urlChanged);
到目前为止,这有点奏效,但有一些怪癖:
- 虽然当用户单击 WhatsApp link 时事件会立即触发(通过触发警报进行检查),但系统浏览器实际打开需要大约两三秒钟的时间。
- 在等待这 2-3 秒并返回到应用程序时,用户会看到一个 inappbrowser 错误页面,提示
whatsapp://
link 无法打开 ("unknown url scheme")。
为了缓解第 2 点,我还在事件侦听器中尝试了以下操作,但没有成功(行为完全相同):
urlChanged = function(event) {
if(event.url.startsWith("whatsapp://")) {
// stop loading the whatsapp:// link in inappbrowser
browser.stop();
// go back in history to display page where whatsapp:// link was on
browser.history.back();
window.open(event.url, "_system");
return;
}
}
browser.addEventListener("loadstart", urlChanged);
你能指导我如何解决第 1 点和第 2 点吗?
所以我得到了以下代码:
openWithSystemBrowser = function(url) {
window.open(url, "_system");
location.href = "index.html";
};
shareOnWhatsapp = function(url) {
openWithSystemBrowser(url);
};
/**
* Handles URL changes in in-app browser, e.g. to handle logouts or
* unsuccessful logins
*/
urlChanged = function(event) {
if(event.url.startsWith("http://whatsapp://")) {
shareOnWhatsapp(event.url.substr("http://".length));
return;
}
if(event.url.startsWith("whatsapp://")) {
shareOnWhatsapp(event.url);
return;
}
};
这当然有点蹩脚,因为你总是被带回 index.html,但就我的目的而言,这已经足够了。有兴趣看看是否有人找到了更优雅的解决方案。
它也解决了打开系统浏览器之前的2-3秒延迟,但我不知道为什么,坦率地说。
我找到了一个用户体验更好的方法:在系统浏览器中加载外部URL时,我关闭InAppBrowser并用最后一个内部URL重新打开它。
var appUrl = 'https://www.my-website.com';
var app = {
currentUrl: appUrl,
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
onDeviceReady: function() {
app.openBrowser();
},
openBrowser: function() {
var target = '_blank';
var options = [
"location=no",
"clearcache=no",
"clearsessioncache=no",
"footer=no",
"hardwareback=no",
"hideurlbar=yes",
"zoom=no",
"hidenavigationbuttons=no",
"toolbar=yes",
"hidespinner=yes",
"toolbarcolor=#000000",
"toolbartranslucent=no",
"navigationbuttoncolor=#ffffff",
"closebuttoncolor=#000000",
"closebuttoncaption="
];
browser = cordova.InAppBrowser.open(app.currentUrl, target, options.join());
// reopen the browser if it was closed via "Done" button
browser.addEventListener('exit', function(){ app.openBrowser(); } );
// open external urls in system browser window
browser.addEventListener('loadstart', function(event){ app.handleUrl(event.url, browser); });
},
handleUrl: function(url, browser) {
var extension = url.split('.').pop();
// load internal urls that are not pdf files in the app browser
if (extension != 'pdf' && url.startsWith(appUrl)) {
app.currentUrl = url;
return;
}
// open website in system browser window
var ref = cordova.InAppBrowser.open(url, '_system', 'location=no');
// since the inapp browser is loading the website too, close it and open it again with the last internal url visited
browser.close();
app.openBrowser();
return;
}
};
app.initialize();