React Native - открыть ссылки в браузере
Привет, я использую интерактивный веб-просмотр, чтобы отобразить некоторые html,
я хочу, чтобы всякий раз, когда пользователь щелкает ссылку внутри этого html, он откроет браузер пользователя с этой ссылкой.
возможно?
Изменить 1:
В итоге я использовал этот пакет: npmjs.com/package/react-native-communications, который открывает браузер.
Я вызываю браузер для открытия onNavigationStateChange при изменении URL-адреса.
Теперь дело в том, что WebView продолжает обрабатывать запрос, хотя я переехал в браузер, как я могу остановить запрос?
Ответы
Ответ 1
Вот полное рабочее решение:
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);
}
}}
/>
);
}
}
Он использует простой WebView, перехватывает любое изменение URL и, если этот URL отличается от исходного, останавливает загрузку, предотвращает изменение страницы и открывает ее в OS Navigator.
![ios simulator]()
Ответ 2
Linking.openURL(url).catch(err => console.error('An error occurred', err));
https://facebook.github.io/react-native/docs/linking.html
Ответ 3
Это мое решение. Поскольку он не является общим, вы можете улучшить введенный 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}
/>
)
}
}
Ответ 4
Большая проблема с использованием "stopLoading()" заключается в том, что в Android он отключает дальнейшие нажатия на любые другие ссылки с этой исходной страницы.
Компонент WebView выделяется из ядра RN и в руки сообщества. Если вместо этого вы используете эту версию (https://github.com/react-native-community/react-native-webview), вы можете использовать опору "onShouldStartLoadWithRequest" на iOS и Android, что делает ее намного более элегантной.
Построение Дэмиена Варрона действительно полезный ответ, вот пример того, как вы могли бы использовать этот реквизит, чтобы избежать stopLoading, который работает кроссплатформенно:
onShouldStartLoadWithRequest={event => {
if (event.url !== uri) {
Linking.openURL(event.url)
return false
}
return true
}}
А вот как вы можете это сделать, если вашим источником является HTML, а не URI:
onShouldStartLoadWithRequest={event => {
if (event.url.slice(0,4) === 'http') {
Linking.openURL(event.url)
return false
}
return true
}}
Как указал basbase, вы также можете сделать это следующим образом (я добавил раздел about: blank). Я планирую проб и ошибок больше, чтобы увидеть, какие из них лучше.
onShouldStartLoadWithRequest={event => {
if (!/^[data:text, about:blank]/.test(event.url)) {
Linking.openURL(event.url)
return false
}
return true
}}
Ответ 5
Я нашел способ сделать это, хотя это решение для iOS!
Вот пошаговые инструкции:
- Свяжите библиотеку
'RCTLinkingIOS'
с вашим проектом. Я использовал CocoaPods, чтобы так. -
В вашем WebView добавьте "onShouldStartLoadWithRequest". Например
<WebView source={{ html: content }} onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest}/>
-
Добавьте функцию this.onShouldStartLoadWithRequest
. Верните TRUE или FALSE в зависимости от того, хотите ли вы перейти по ссылке в вашем WebView. Это в основном эквивалент реализации UIWebViewDelegate, которую вы использовали бы при реализации в нативном коде (Swift или Objective-C).
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
});
}
-
Убедитесь, что вы также импортировали Linking в ваш источник JavaScript:
import { AppRegistry, View, WebView, Linking } from 'react-native';
Это должно делать свое дело.
Для получения дополнительной информации см. Собственные документы по реагированию: https://facebook.github.io/react-native/docs/linking.html.
Ответ 6
Вы хотите прочитать это: https://facebook.github.io/react-native/docs/linkingios.html
Возможно, просто проверьте ссылку выше, и все должно быть хорошо!
Другие ссылки:
https://github.com/ivanph/react-native-webintent
https://www.npmjs.com/package/react-native-browser
Ответ 7
Это можно сделать кросс-платформенным способом, используя встроенный класс Linking и react-native-webview-bridge.
const generateLink = (text, url) => {
if (url) {
return `<a href='#' onclick='WebViewBridge.send("${url}"); return false;'>${text}</a>`;
} else {
return text;
}
};
const generateHtml = () => `<!DOCTYPE html><html><body>
${generateLink('Link text', 'http://example.com')}
</body></html>`;
С компонентом WebViewBridge
, созданным следующим образом:
<WebViewBridge
javaScriptEnabled
renderLoading={() => <ActivityIndicator animating size="large" />}
source={{ html: generateHtml() }}
onBridgeMessage={url => Linking.openURL(url)}
/>
Ответ 8
В дополнение к отличному ответу fooobar.com/questions/240486/...: При использовании source={{html: '...'}}
вы можете проверить изменение внешнего URL-адреса с помощью: if (!/^data:text/.test(event.url)) {
Ответ 9
Если stopLoading()
в onNavigationStateChange
на Android не работает,
this.webview.stopLoading();
setTimeOut( () => {
Linking.openURL(event.url)
}, 1000);
Это сработало хорошо.
Ответ 10
Решение для тех, кто использует выставку:
import * as WebBrowser from 'expo-web-browser';
import { WebView } from 'react-native-webview';
...
render() {
return (
<WebView
source={{
uri: uri
}}
ref={ (ref) => { this.webview = ref; } }
onNavigationStateChange={ (event) => {
if (event.url !== uri) {
this.webView.stopLoading();
WebBrowser.openBrowserAsync(event.url);
}
}}
/>
);
}
WebBrowser
устанавливается через: expo install expo-web-browser