Hallo, ich verwende die Webansicht von react native, um etwas HTML anzuzeigen. Ich möchte, dass jedes Mal, wenn ein Benutzer auf einen Link in diesem HTML klickt, der Browser des Benutzers mit diesem Link geöffnet wird.
ist das möglich?
Bearbeiten 1:
Am Ende habe ich dieses Paket verwendet: npmjs.com/package/react-native-communications, das den Browser öffnet. Ich rufe den Browser auf, um auf onNavigationStateChange zu öffnen, wenn sich die URL ändert.
Die Sache ist jetzt, dass das WebView die Anfrage weiterhin verarbeitet, obwohl ich zum Browser gewechselt bin. Wie kann ich die Anfrage stoppen?
react-native
Matan Kadosh
quelle
quelle
Antworten:
Hier ist eine vollständige Arbeitslösung:
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); } }} /> ); } }
Es verwendet ein einfaches WebView, fängt jede URL-Änderung ab. Wenn diese URL von der ursprünglichen abweicht, stoppt es das Laden, verhindert Seitenänderungen und öffnet sie stattdessen im OS Navigator.
quelle
event.navigationType === 'click'
die if-Bedingung hinzuzufügen , um nur Klickereignisse im Browser abzufangen ...ref="webview"
und dannthis.refs.webview.stopLoading()
.navigationType
auf der Veranstaltung, nururl
,loading
,canGoForward
,canGoBack
,target
, undtitle
. Es ist ein wenig schlampig,canGoBack
funktioniert aber, wenn Sie alle Links in der WebView verarbeiten möchten und den Benutzer niemals in der WebView navigieren lassen möchten.Ein großes Problem bei der Verwendung von "stopLoading ()" ist, dass unter Android das weitere Tippen auf andere Links von dieser Quellseite deaktiviert wird.
Die WebView-Komponente wird aus dem Kern-RN in die Hände der Community aufgeteilt. Wenn Sie stattdessen diese Version verwenden ( https://github.com/react-native-community/react-native-webview ), können Sie die Requisite "onShouldStartLoadWithRequest" sowohl für iOS als auch für Android verwenden, wodurch dies viel eleganter wird.
Aufbauend auf Damien Varrons wirklich hilfreicher Antwort finden Sie hier ein Beispiel dafür, wie Sie diese Requisite nutzen können, um zu vermeiden, dass stopLoading plattformübergreifend funktioniert:
Und so können Sie es tun, wenn Ihre Quelle HTML im Gegensatz zu einer URI ist:
Wie basbase betonte, können Sie dies auch auf diese Weise tun (ich habe das about: blank-Teil hinzugefügt). Ich habe vor, mehr zu probieren, um herauszufinden, was am besten hält.
quelle
/^[data:text, about:blank]/
wird so viele Dinge zusammenbringen, weil[]
es eine Charakterklasse ist. Sie könnten/^(?:data:text|about:blank)/
stattdessen gemeint haben . Siehe diese Antwort .https://facebook.github.io/react-native/docs/linking.html
quelle
Das ist meine Lösung. Da es nicht generisch ist, können Sie das injizierte Javascript entsprechend Ihren Anforderungen verbessern
quelle
Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined.
Wie haben Sie diesen Fehler überwunden? Ich verstehe das immer wieder mit Ihrer Lösung. Auch hier gibt es ein Problem bei der Reaktion auf natives Repo - github.com/facebook/react-native/issues/10865 .data !== "undefined"
sollte jedoch inif
Block hinzugefügt werden .Ich habe einen Weg gefunden, dies zu tun, es ist jedoch eine reine iOS-Lösung!
Hier finden Sie eine schrittweise Anleitung:
'RCTLinkingIOS'
Bibliothek mit Ihrem Projekt. Ich habe dazu CocoaPods verwendet.Fügen Sie in Ihrer WebView "onShouldStartLoadWithRequest" hinzu. Zum Beispiel
<WebView source={{ html: content }} onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest} />
Fügen Sie die
this.onShouldStartLoadWithRequest
Funktion hinzu. Geben Sie TRUE oder FALSE zurück, je nachdem, ob Sie dem Link in Ihrer WebView folgen möchten oder nicht. Dies entspricht im Wesentlichen der UIWebViewDelegate-Implementierung, die Sie verwenden würden, wenn Sie sie in nativem Code (Swift oder Objective-C) implementieren.Stellen Sie sicher, dass Sie auch Linking in Ihre Javascript-Quelle importieren:
import { AppRegistry, View, WebView, Linking } from 'react-native';
Das sollte den Trick machen.
Weitere Informationen finden Sie in den reaktionsnativen Dokumenten: https://facebook.github.io/react-native/docs/linking.html
quelle
Es ist möglich, dies plattformübergreifend mithilfe der integrierten Linking- Klasse und der reaktionsnativen Webview-Bridge zu tun .
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>`;
Mit einer so
WebViewBridge
gerenderten Komponente:<WebViewBridge javaScriptEnabled renderLoading={() => <ActivityIndicator animating size="large" />} source={{ html: generateHtml() }} onBridgeMessage={url => Linking.openURL(url)} />
quelle
Zusätzlich zu der hervorragenden Antwort https://stackoverflow.com/a/40382325/10236907 : Bei Verwendung
source={{html: '...'}}
können Sie nach einer externen URL-Änderung suchen, indem Sie:if (!/^data:text/.test(event.url)) {
quelle
Lösung für diejenigen, die die Messe nutzen:
WebBrowser
wird installiert über:expo install expo-web-browser
quelle
Sie sollten dies lesen: https://facebook.github.io/react-native/docs/linkingios.html
Es ist möglich, überprüfen Sie einfach den Link oben und Sie sollten alle gut sein!
Andere Links:
https://github.com/ivanph/react-native-webintent
https://www.npmjs.com/package/react-native-browser
quelle
<TouchableHighlight onPress={this.function}> <Text>link goes here...</Text></TouchableHighlight>
. Diese Funktion wäre eine Funktion, die die oben genannten npm-Pakete verwendet. @MatanKadoshWenn
stopLoading()
inonNavigationStateChange
Android nicht funktioniert,Es hat gut funktioniert.
quelle
Ich hatte viele Probleme mit dieser Lösung, als ich die lokale HTML-Datei nur unter iOS verwendete. Wenn ich beispielsweise Instagram in meine Webansicht eingebettet habe, wird es automatisch geöffnet. Um es zu lösen, habe ich hinzugefügt (nur für iOS):
quelle
Wenn Sie versuchen, eine Weiterleitungs-URL zu öffnen, und Sie eine Fehlermeldung von einer Android-Absicht wie "err_unknown_url_scheme" erhalten.
Überprüfen Sie, was es zu öffnen versucht, da es möglicherweise Android-Verkehr erkannt und versucht hat, in der entsprechenden App zu öffnen.
Wenn Sie möchten, dass es trotzdem in der Webansicht geöffnet wird und Sie eine Absicht von einer Umleitung zurückerhalten, fangen Sie es in onNavigationStateChange ab und schreiben Sie es neu:
quelle
Ich hatte Probleme damit. Mein Anwendungsfall bestand darin, externe Links in einem separaten Browser zu öffnen. Diese Lösung hat bei mir funktioniert.
quelle