在 ionic 应用程序中使用系统浏览器打开所有链接

Posted

技术标签:

【中文标题】在 ionic 应用程序中使用系统浏览器打开所有链接【英文标题】:Open all links using system browser inside an ionic app 【发布时间】:2016-05-05 03:33:09 【问题描述】:

我需要在系统浏览器中打开我的应用某个部分内的所有链接。诀窍是这些链接来自外部源(API),所以我无法添加帮助我在外部打开链接的ng-click 函数。

我正在使用 in-app-browser 插件 (ng-cordova)。事实上,我还有其他在外部打开的链接,但在这种情况下,链接可以位于内容的任何部分,所以我的问题是如何在加载后将 ng-click 指令添加到所有链接?或者如果可能的话,如何配置应用内浏览器插件以在系统浏览器中打开所有链接?

顺便说一句,简单的链接即使在 inappbrowser 中也打不开:我点击它们并没有任何反应。

感谢您的帮助

【问题讨论】:

您说这些链接来自 API。那么,您为什么不使用 javascript 正则表达式在从 API 获得的字符串中实现基本的搜索和替换? 这是唯一的方法吗?我的意思是,我可以遍历所有 元素,但我试图避免这种情况,我认为可能有一种方法可以在全球范围内实现这一点,也许可以配置应用内浏览器插件或类似的东西 Aa AngularJS 不会自动拦截原生 JavaScript 调用,它也不能用角度指令替换它们 我想知道这是否可以使用 inappbrowser.loadstart 事件监听来实现? 【参考方案1】:

AFAIK 无法自动执行此操作,您必须使用应用内浏览器 js 代码在每个平台上一致地打开外部链接。

您的问题没有给出服务器返回内容的明确示例,因此我假设您正在获取完整的 html 块并且只是在屏幕上呈现它。假设一个请求返回一些基本的东西:

<div id="my-links">
   <a href='http://externallink.com'> External Link 1 </a>
   <a href='http://externallink.com'> External Link 2 </a>
   <a href='http://externallink.com'> External Link 3 </a>
</div>

您的请求如下所示:

$http.get('givemelinks').success(function(htmlData)
   $scope.myContent = htmlData;
)

如果您可以访问服务器端并且可以进行更改:

在您的请求中添加一个“inappbrowser”参数,以检测它是否应该返回与 inappbrowser 兼容的链接,并将来自您的服务器的响应更改为:

if (inappbrowser) 
<div id="my-links">
   <div ng-click='openExternal($event)' data-external='http://externallink.com'> External Link 1 </div>
   <div ng-click='openExternal($event)' data-external='http://externallink.com'> External Link 2 </div>
   <div ng-click='openExternal($event)' data-external='http://externallink.com'> External Link 3 </div>
</div>
 else 
 <div id="my-links">
   <a href='http://externallink.com'> External Link 1 </a>
   <a href='http://externallink.com'> External Link 2 </a>
   <a href='http://externallink.com'> External Link 3 </a>
</div>

并且有一个通用的 openExternal 方法:

$scope.openExternal = function($event)
  if ($event.currentTarget && $event.currentTarget.attributes['data-external'])
  window.open($event.currentTarget.attributes['data-external'], '_blank', 'location=yes');

如果无法更改服务器端

解析响应并用 ng-clicks 替换链接:

$http.get('givemelinks').success(function(htmlData)
   htmlData = htmlData.replace(/href='(.*)'/,'ng-click="openExternal($event)" data-external="$1"').replace(/<a/,"<div").replace(/a>/,"div>")
   $scope.myContent = htmlData;
)

并使用与上面相同的 openExternal 方法。

我正在用 div 替换锚点,以防止更改应用程序路线。这可能不是每个应用都需要的。

为了使它更好,你应该将它捆绑在一个open-external 指令中,这样你就可以在多个控制器中使用它并保持它们更干净。

【讨论】:

当我尝试您的回答时,我仍然无法在我的应用程序中打开链接。当我将$event.currentTarget.attributes['data-external'] 登录到控制台时,我看到:data-external="http://loremipsum.com/"Window.open() 需要一个链接作为第一个参数,而不是前面的 data-external=。所以我将.value 添加到$event.currentTarget.attributes['data-external'],当我将($event.currentTarget.attributes['data-external'].value)记录到控制台时,我只看到了链接,更重要的是,当我用它替换window.open() 的第一个参数时,我能够打开链接。 【参考方案2】:

因为 HTML 已经在 Angular 中呈现,并且 inAppBrowser 插件只有在被显式 Javascript 调用时才能工作,所以除了手动更改 HTML 或使用纯 JavaScript 之外,您无能为力。

更改 HTML 只是个坏主意®,尤其是如果您尝试使用正则表达式匹配来做到这一点。

剩下的就是javascript了:

Restangular.all('stories').getList().then(function(stories)
  $scope.stories = stories;
  updateLinks();
);

function updateLinks()
  //use $timeout wait for items to be rendered before looking for links
  $timeout(function()
      var $links = document.querySelectorAll(".stories .story a");
      for(var i =0; i < $links.length; i++) 
        var $link = $links[i];
        var href = $link.href;
        console.log("Hijacking link to ", href);
        $link.onclick = function(e)
          e.preventDefault();
          var url = e.currentTarget.getAttribute("href");
          window.cordova.inAppBrowser.open(url, "_system");
        
      
    );

【讨论】:

【参考方案3】:

安装下一个插件:

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git

现在,您可以使用_system_blank_self 作为目的地:

window.open(url, '_blank');

更多信息:https://www.thepolyglotdeveloper.com/2014/07/launch-external-urls-ionicframework/

【讨论】:

【参考方案4】:

您可以覆盖默认链接标签功能,如下所示:

https://www.thepolyglotdeveloper.com/2014/12/open-dynamic-links-using-cordova-inappbrowser/

最好的,

【讨论】:

【参考方案5】:
<ul>
<li> <a href="#"  ng-click='openlink($event)' data-link='https://www.link1.com'> Link 1 </a></li>  
<li> <a href="#"  ng-click='openlink($event)' data-link='https://www.link2.com'> Link2 </a></li>  
<li> <a href="#"  ng-click='openlink($event)' data-link='https://www.link3.com'> Link 3 </a></li>  
</ul>

在控制器中 -

 angular.module('app', [])
    .controller('LinkCtrl', function($scope) 
         $scope.openlink = function($event)
                           
              if ($event.currentTarget && $event.currentTarget.attributes['data-link'])
                    
                   window.open($event.currentTarget.attributes['data-link'], '_system', 'location=yes');
                    
                

    )

【讨论】:

以上是关于在 ionic 应用程序中使用系统浏览器打开所有链接的主要内容,如果未能解决你的问题,请参考以下文章

来自 http url 的 Ionic 3 (cordova) 应用程序不会作为应用程序打开,但它会在浏览器中打开

Ionic - 在 Apple 地图应用中打开导航方向

无法通过邮件中的链接打开 Ionic App 中的页面

在使用 Ionic 3 允许系统权限后,Android 设备相机未打开

在 InAppBrowser 中打开链接时维护标题

在为Ionic Cordova应用程序提供服务时,如何打开标签或窗口?