react-native-webview的stopLoading方法导致网站死机

Fen*_*cer 5 javascript react-native react-native-webview

我想在 react-native 中拦截我的 webview 中链接的点击并执行自定义操作,而不是按照官方指南中的描述导航到链接的目标。这是我所做的:

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);
        }
    };
Run Code Online (Sandbox Code Playgroud)

}

如果我单击该 webview 中的链接,则 URL 将按预期在系统浏览器中打开。然而,问题是之后 webview 被冻结了。我无法点击更多链接,甚至无法滚动页面。当然,这不是应该的。重点是在其他地方打开一个链接,以便 webview 中的页面保持可用。结果将保持不变,即使我删除了Linking-part。然后页面会在点击链接时冻结。

有谁知道该怎么做?我想 stopLoading-method 不仅仅是中止加载。它是否也可能取消当前页面上正在运行的任何 Javascript?如果是这样,我可以阻止吗?

Fen*_*cer 6

由于这个拉取请求,我至少找到了适合我的案例的解决方案。我没有使用onNavigationStateChangeand 而是stopLoading转向了onShouldStartLoadWithRequest. false在此事件的回调方法中,您可以简单地通过返回或来定义是否应丢弃当前 webview 的请求true。所以你会得到这样的东西:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,“做什么”部分。好吧,我也想回答我的其他问题,并深入研究了react-native-webview的代码(这根本没有乐趣......注释呢?->“让代码说话”->好吧,它没有) 。花了一些时间从一个委托目标跳转到下一个委托目标后,某个地方的stopLoading调用似乎被移交给了本机 WebView。因此 Android 和 iOS 的行为也可能完全不同(我目前只为 Android 开发)。至于“我可以阻止”——整个问题的一部分,我可以说:“不”。当然,最有趣的部分是“它stopLoading实际上做了什么?我在某处读到它确实阻止了当前页面上的链接被点击。但这只是一个未经证实的声明。当我谈到原生Android时—— WebView-documentation我找到了非常非常好的解释“停止当前负载。”(去谷歌,是的)。然后我失去了深入挖掘的动力。好吧,除非有人比我更开明,可以想出一个更详细的解释我可能会接受我自己的答案,因为它至少是我面临的开发问题的解决方案。