4

在我们的 PhoneGap iOS 应用程序中,我们使用 InAppBrowser 插件来显示一些内容,我们需要在 Safari 中从 InAppBrowser 中打开一个页面。

我们如何在 Safari 中打开 InAppBrowser 中的链接?

4

4 回答 4

6

来自phonegap 文档

在新的 InAppBrowser 实例、当前浏览器实例或系统浏览器中打开 URL。

var ref = window.open(url, target, options);
  • ref:对 InAppBrowser 窗口的引用。(InAppBrowser)
  • url:要加载的 URL(字符串)。如果 URL 包含 Unicode 字符,请在此调用 encodeURI()。
  • target:加载URL的目标,可选参数,默认为_self。(细绳)

    • _self:如果 URL 在白名单中,则在 Cordova WebView 中打开,否则在 InAppBrowser 中打开。
    • _blank:在 InAppBrowser 中打开。
    • _system:在系统的网络浏览器中打开。

因此,要回答您的问题,请使用:

window.open(your_url, '_system', opts);

请注意,该域需要被列入白名单。


2014 年 4 月 25 日更新:

我想我有点误解了这个问题(感谢评论者@peteorpeter)——您希望有某种方法可以单击 InAppBrowser 中的链接并在系统浏览器中打开该链接(例如 iOS 上的 Mobile Safari)。这是可能的,但需要应用程序开发人员和负责页面链接的人员之间进行一些深思熟虑和合作。

当您创建一个 IAB 实例时,您会得到一个对它的引用:

var ref = window.open('http://foo.com', '_blank', {...});

您可以在该引用上注册一些事件侦听器:

ref.addEventListener('loadStart', function(event){ ... });

每次 IAB 的 URL 更改(例如单击链接、服务器返回 302 等)时都会触发此特定事件,您可以检查新 URL。

要闯入系统浏览器,您需要在 URL 中定义某种标志。你可以做很多事情,但对于这个例子,让我们假设systemBrowserurl 中有一个标志:

.....html?foo=1&systemBrowser=true

您将在事件处理程序中查找该标志,并在找到后跳到系统浏览器:

ref.addEventListener('loadStart', function(event){
    if (event.url.indexOf('systemBrowser') > 0){
        window.open(event.url, '_system', null);
    }
});

请注意,这不是检测 url 中标志的最佳方法(可能会导致误报),我很确定 PhoneGap 白名单规则仍然适用。

于 2013-07-10T19:48:54.793 回答
3

不幸的是target=_system,在 InAppBrowser 中不起作用。(不过,如果链接源自父应用程序,这将起作用。)

您可以将事件侦听器添加到 IAB 并嗅探特定的 url 模式,正如您在评论中提到的那样,如果这适合您的用例。

iab.addEventListener('loadstart', function(event) {
   if (event.url.indexOf("openinSafari") != -1) { 
        window.open(event.url, '_system'); 
    } 
}

这里的“事件”不是真正的浏览器事件——它是 IAB 插件的构造——并且不支持event.preventDefault(),因此 IAB 还将加载 url(除了 Safari)。您可能会尝试在 IAB中处理该事件,例如:

iab.addEventListener('loadstop', function(event) {
   iab.executeScript('functionThatPreventsOpenInSafariLinksFromGoingAnywhere');  
}

...我没有测试过。

于 2014-04-25T16:28:35.013 回答
2

This message is for clarification:

If you open an another with window.open by catching a link on loadstart, it will kill yor eventhandlers that assigned to first IAB.

For example,

iab = window.open('http://example.com', '_blank', 'location=no,hardwareback=yes,toolbar=no');
iab.addEventListener('loadstop', function(event) {console.log('stop: ' + event.url);});
iab.addEventListener('loaderror', function(event) { console.log('loaderror: ' + event.message); });
iab.addEventListener('loadstart', function(event) {
    if (event.url.indexOf("twitter") != -1){
        var ref2 = window.open(event.url, '_system', null);

    }
});

When the second window.open executed, it will kill all the event listeners that you binded before. Also loadstop event will not be fired after that window.open executed.

I'm finding another way to avoid but nothing found yet..

于 2014-06-11T10:07:17.020 回答
0

window.open()在 InAppBrowser 中对我不起作用,无论我是否添加对 cordova.js 的脚本引用以获得对 的支持window.open(...'_system'),所以我想出了以下解决方案,该解决方案通过主题标签,以便可以在那里打开它。

在 InAppBrowser 实例内部(我使用的是 AngularJS,但如果你使用的是 jQuery ,你可以替换angular.elementjQuery或者):$

angular.element(document).find('a').on('click', function(e) {
    var targetUrl = angular.element(this).attr('href');
    if(targetUrl.indexOf('http') === 0) {
        e.preventDefault();
        window.open('#' + targetUrl);
    }
});

请注意,这是window.open上面的原生,而不是 cordova.js 的window.open。此外,处理程序代码假定所有以 开头的 URLhttp都应从外部加载。您可以根据需要更改过滤器,以允许在 IAB 中加载某些 URL,而在 Safari 中加载其他 URL。

然后,在创建 InAppBrowser 的父代码中:

inAppBrowser.addEventListener('loadstart', function(e) {
    if(e.url.indexOf('#') > 0) {
        var tunneledUrl = e.url.substring(e.url.indexOf('#') + 1);
        window.open(tunneledUrl, '_system', null);
    }
});

使用此解决方案,IAB 将保留在原始页面上,并且不会触发返回导航箭头出现,并且loadstart处理程序能够在 Safari 中打开请求的 URL。

于 2014-09-26T22:56:59.330 回答