最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - The method stopLoading of react-native-webview causes the website to freeze - Stack Overflow

programmeradmin1浏览0评论

I want to intercept clicks on a link in my webview in react-native and perform a custom action instead of navigating to the target of the link as described in the official guide. Here's what I do:

import React from 'react';
import {View, Linking} from 'react-native';
import AsyncStorage from '@react-native-munity/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 = ".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 ()
                    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);
        }
    };

}

If I click on a link in that webview the URL will be opened in a the systems Browser as expected. The problem is however that afterwards the webview is frozen. I can't click any more Links or even scroll the page. Of course this is not as it should be. The whole point is to open a link somewhere else so that the page in the webview remains usable. The result will remain the same, even if I remove the Linking-part. Then the page just freezes on a link-click.

Does anyone know what to do? I guess the stopLoading-method does a little more than just abort loading. Does it maybe also cancel any running Javascript on the current page? If so, can I prevent that?

I want to intercept clicks on a link in my webview in react-native and perform a custom action instead of navigating to the target of the link as described in the official guide. Here's what I do:

import React from 'react';
import {View, Linking} from 'react-native';
import AsyncStorage from '@react-native-munity/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);
        }
    };

}

If I click on a link in that webview the URL will be opened in a the systems Browser as expected. The problem is however that afterwards the webview is frozen. I can't click any more Links or even scroll the page. Of course this is not as it should be. The whole point is to open a link somewhere else so that the page in the webview remains usable. The result will remain the same, even if I remove the Linking-part. Then the page just freezes on a link-click.

Does anyone know what to do? I guess the stopLoading-method does a little more than just abort loading. Does it maybe also cancel any running Javascript on the current page? If so, can I prevent that?

Share Improve this question edited Jul 15, 2019 at 15:59 Fencer asked Jul 15, 2019 at 15:52 FencerFencer 1,08812 silver badges29 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

I have found a solution at least for my case thanks to this pull request. Instead of using onNavigationStateChange and stopLoading I turned to onShouldStartLoadWithRequest. In the callback method for this event you can define whether or not the request should be discarded as far as the current webview is concerned or not simply by returning false or true. So you get something like this:

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;
    }
}

So far for the "what to do"-part. Well I also wanted to answer my other questions and dug into the code of react-native-webview (which was no fun at all... what about ments? -> 'let the code speak' -> well it doesn't). After spending some time jumping from one delegation target to the next, somewhere the stopLoading-call seems to be handed over to the native WebView. So the behaviour may also be pletely different for Android and iOS (I'm developing only for Android currently). As for the "can I prevent"-part of the whole question I can say: "No". Of course the most interesting part would have been "what does stopLoading actually do? Somewhere I read that it prevents Links on the current page from being clicked, indeed. But that was just a non-proven statement. As I got to the native Android-WebView-documentation I found the very very good explanation "Stops the current load." (go Google, yay). Then I lost all motivation to dig deeper. Well, unless someone more enlightned than me, can e up with a more elaborate explanation I will problably accept my own answer, since it is at least a solution to the dev-problem I faced.

发布评论

评论列表(0)

  1. 暂无评论