React Native - 在浏览器中打开链接

Mat*_*osh 52 react-native

嗨,我正在使用本机的webview来显示一些HTML,我希望每当用户点击该html内的链接时,它将打开用户的浏览器与该链接.

那可能吗?

编辑1:

我最终使用了这个软件包:npmjs.com/package/react-native-communications打开浏览器.当URL更改时,我调用浏览器在onNavigationStateChange上打开.

现在的事情是WebView仍然继续处理请求,虽然我已经移动到浏览器,我该如何停止请求?

dam*_*net 98

这是一个完整的工作解决方案:

import React, { Component } from 'react';
import { WebView, Linking } from 'react-native';

export default class WebViewThatOpensLinksInNavigator extends Component {
  render() {
    const uri = 'http://stackoverflow.com/questions/35531679/react-native-open-links-in-browser';
    return (
      <WebView
        ref={(ref) => { this.webview = ref; }}
        source={{ uri }}
        onNavigationStateChange={(event) => {
          if (event.url !== uri) {
            this.webview.stopLoading();
            Linking.openURL(event.url);
          }
        }}
      />
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

它使用简单的WebView,拦截任何URL更改,如果该URL与原始URL不同,则停止加载,阻止页面更改,并在OS Navigator中将其打开.

ios模拟器

  • 这适用于我,但我建议将`event.navigationType ==='click'`添加到if条件中以仅捕获浏览器中的点击事件... (8认同)
  • 在下面的答案中使用 onShouldStartLoadWithRequest 。android 6 有这个问题 (2认同)

ooo*_*ala 19

Linking.openURL(url).catch(err => console.error('An error occurred', err));
Run Code Online (Sandbox Code Playgroud)

https://facebook.github.io/react-native/docs/linking.html


小智 15

这是我的解决方案.由于它不是通用的,您可以根据您的要求改进注入的javascript

import {
  View,
  WebView,
  Linking,
} from 'react-native';

const injectScript = `
  (function () {
    window.onclick = function(e) {
      e.preventDefault();
      window.postMessage(e.target.href);
      e.stopPropagation()
    }
  }());
`;

class MyWebView extends React.Component {

  onMessage({ nativeEvent }) {
    const data = nativeEvent.data;

    if (data !== undefined && data !== null) {
      Linking.openURL(data);
    }
  }

  render() {
    return (
      <WebView
        source={{ html: this.props.html }}
        injectedJavaScript={injectScript}
        onMessage={this.onMessage}
      />
    )
  }
}
Run Code Online (Sandbox Code Playgroud)


tim*_*uld 14

使用“ stopLoading()”的一个大问题是,在Android上,它禁用了对该源页面上任何其他链接的进一步点击。

WebView组件正在从核心RN中分离出来,并交到社区的手中。如果改用该版本(https://github.com/react-native-community/react-native-webview),则可以在iOS和Android上使用“ onShouldStartLoadWithRequest”道具,这使它更加优雅。

在Damien Varron真正有用的答案的基础上,下面是一个示例,说明如何利用该道具避免跨平台工作的stopLoading:

onShouldStartLoadWithRequest={event => {
    if (event.url !== uri) {
        Linking.openURL(event.url)
        return false
    }
    return true
}}
Run Code Online (Sandbox Code Playgroud)

如果您的源是HTML而不是URI,则可以按照以下方法进行操作:

onShouldStartLoadWithRequest={event => {
    if (event.url.slice(0,4) === 'http') {
        Linking.openURL(event.url)
        return false
    }
    return true
}}
Run Code Online (Sandbox Code Playgroud)

正如basbase所指出的,您也可以用这种方式(我已经添加了about:blank部分)。我计划进行更多的反复试验,以查看哪种效果最好。

onShouldStartLoadWithRequest={event => {
    if (!/^[data:text, about:blank]/.test(event.url)) {
        Linking.openURL(event.url)
        return false
    }
    return true
}}
Run Code Online (Sandbox Code Playgroud)


Boc*_*ica 7

我找到了一种方法,但它只是一个iOS解决方案!

以下是分步说明:

  1. 'RCTLinkingIOS'库链接到您的项目.我使用CocoaPods.
  2. 在您的WebView中添加"onShouldStartLoadWithRequest".例如

    <WebView source={{ html: content }} onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest} />

  3. 添加this.onShouldStartLoadWithRequest功能.根据您是否要关注WebView中的链接,返回TRUE或FALSE.这基本上等同于在本机代码(Swift或Objective-C)中实现它时使用的UIWebViewDelegate实现.

    onShouldStartLoadWithRequest = (event) => {
         Linking.canOpenURL(event.url).then(supported => {
             if (supported) {
                 Linking.openURL(event.url);
             } else {
                 console.log('Don\'t know how to open URI: ' + event.url);
             }
             return false
         });
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 确保在您的javascript源中导入链接:

    import { AppRegistry, View, WebView, Linking } from 'react-native';

这应该够了吧.

有关更多信息,请参阅react-native docs:https: //facebook.github.io/react-native/docs/linking.html


小智 7

@Damusnet 只是偶尔为我工作。我查看了它,这是我更新的代码,它适用于我使用react-native-webview 11.4.3。

import React from 'react';
import { WebView, Linking } from 'react-native';

const WebviewScreen = () => {
  const uri = 'http://stackoverflow.com/questions/35531679/react-native-open-links-in-browser';

  return (
    <WebView
    source={{ uri }}
    onShouldStartLoadWithRequest={(request) => {
      if (request.url !== uri) {
        Linking.openURL(request.url);
        return false;
      }

      return true;
    }}
  />    
  )
}
Run Code Online (Sandbox Code Playgroud)


小智 5

<WebView
      source={{uri: this.state.src}}
      ref={(webView) => {
        this.webView.ref = webView;
      }}
      onNavigationStateChange={(navState) => {
        this.webView.canGoBack = navState.canGoBack;
        if (!navState.url.includes('yourdomain.com')) {
          Linking.openURL(navState.url);
          return false;
        }
      }}
      onShouldStartLoadWithRequest={(event) => {
        if (!event.url.includes('yourdomain.com')) {
          Linking.openURL(event.url);
          return false;
        }
        return true;
      }}
      style={{flex: 1}}
      startInLoadingState={true}
      renderLoading={() => {
        return (
          <View style={[styles.container, styles.horizontal]}>
            <ActivityIndicator size="large" color="#0000ff" />
          </View>
        );
      }}
    />
Run Code Online (Sandbox Code Playgroud)

我在这个问题上遇到了困难,我的用例是在单独的浏览器中打开外部链接。这个解决方案对我有用。


Jam*_*111 0

您需要阅读以下内容:https ://facebook.github.io/react-native/docs/linkingios.html

有可能,只需检查上面的链接即可,一切都会好起来的!

其他链接:

https://github.com/ivanph/react-native-webintent

https://www.npmjs.com/package/react-native-browser