javascript - Metoden stopLoading i react-native-webview får webbplatsen att frysa
Jag vill fånga klick på en länk i min webview i react-native och utföra en egen åtgärd istället för att navigera till länkens mål som beskrivs i den officiella guiden. Här är vad jag gör:
import React from 'react';
import {View, Linking} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {WebView} from 'react-native-webview';
export default class WebViewScreen extends React.Component {
static navigationOptions = {
title: 'Produck',
};
constructor(props) {
super(props);
}
/**
* Defines content and look of the WebViewScreen.
*/
render() {
const DEFAULT_URL = "https://www.myurl.de/index.html";
return (
<View style={{ flex: 1 }}>
<WebView
ref = {webview => {
this.myWebView = webview;
}}
renderLoading = {this.renderLoading}
startInLoadingState = {true}
automaticallyAdjustContentInsets = {true}
source = {{ uri: DEFAULT_URL }}
javaScriptEnabled = {true}
domStorageEnabled = {true}
cacheEnabled = {false}
useWebKit = {true} // use WKWebView on iOS (http://facebook.github.io/react-native/blog/2018/08/27/wkwebview)
onNavigationStateChange={this.handleWebViewNavigationStateChange.bind(this)}
/>
</View>
);
}
handleWebViewNavigationStateChange = newNavState => {
const {url} = newNavState;
if (!url) return;
if (isExternal(url)) {
this.myWebView.stopLoading();
// do something else, e.g.
Linking.openURL(url);
}
};
}
Om jag klickar på en länk i den där webviewen kommer URL:en att öppnas i systemets webbläsare som förväntat. Problemet är dock att webviewen fryser efteråt. Jag kan inte klicka på fler länkar eller ens scrolla på sidan. Självklart är detta inte som det borde vara. Hela poängen är att öppna en länk någon annanstans så att sidan i webviewen förblir användbar. Resultatet blir detsamma, även om jag tar bort Linking-delen. Då fryser sidan bara vid ett länk-klick.
Vet någon vad man ska göra? Jag antar att stopLoading-metoden gör lite mer än att bara avbryta laddning. Avbryter den kanske också någon pågående Javascript på den aktuella sidan? Om så är fallet, kan jag förhindra det?
Svar #1
Jag har hittat en lösning åtminstone för mitt fall tack vare denna pull request. Istället för att använda onNavigationStateChange och stopLoading vände jag mig till onShouldStartLoadWithRequest. I callback-metoden för denna händelse kan du definiera om begäran ska avvisas så långt som den nuvarande webviewen är bekymrad eller inte, helt enkelt genom att returnera false eller true. Så du får något liknande detta:
render() {
...
return(...
<WebView
...
onShouldStartLoadWithRequest={this.handleWebViewRequest.bind(this)}
...
/>
);
}
handleWebViewRequest = request => {
const {url} = request;
if (!url) return false;
if (isExternal(url)) {
Linking.openURL(url);
return false;
} else {
return true;
}
}
Hittills för delen "vad man ska göra". Jag ville också svara på mina andra frågor och grävde i koden för react-native-webview (vilket inte var roligt alls... vad gäller kommentarer? -> 'låt koden tala' -> jo, det gör den inte). Efter att ha spenderat en del tid med att hoppa från en delegationsmål till nästa verkar stopLoading-anropet någonstans överlämnas till den inbyggda WebView. Så beteendet kan också vara helt annorlunda för Android och iOS (jag utvecklar för närvarande bara för Android). När det gäller delen "kan jag förhindra" av hela frågan kan jag säga: "Nej". Självklart skulle den mest intressanta delen ha varit "vad gör stopLoading egentligen? Någonstans läste jag att det förhindrar att länkar på den aktuella sidan klickas, verkligen. Men det var bara ett obevisat påstående. När jag kom till den inhemska Android-WebView-dokumentationen hittade jag den mycket mycket bra förklaringen "Stoppar den aktuella laddningen." (gå Google, yay). Sedan tappade jag all motivation att gräva djupare. Tja, om inte någon mer upplyst än jag kan komma med en mer utförlig förklaring, kommer jag förmodligen att acceptera mitt eget svar, eftersom det åtminstone är en lösning på det utvecklarproblem jag stötte på.
