5

I want to hide a header of a specific page that I embed into a React Native WebView. Currently, I use something like this, to dynamically remove the header:

<WebView 
  ... some other props ...
  injectedJavaScript={'function hideHead(){document.getElementById("head").style.display="none";};hideHead();'}
  />

Sometimes you can still see the header flashing, so I guess this JavaScript gets evaluated after the page loads in the WebView.

Is it possible somehow to add / inject JavaScript or CSS before the page renders to remove that flashing?

5
  • maybe you can render the webview inside a hidden react native view and then show the webview Commented Nov 20, 2015 at 6:49
  • I want the users to be able to follow links inside the WebView. It wouldn't be very nice if it always changed into a new WebView, would it?Right now it injects the JS in every page that loads inside the WebView, but sometimes there is still the flashing header to see. Commented Nov 20, 2015 at 10:52
  • would you get a better result if you reversed the logic, first hiding the header, then showing it when not in a WebView? Commented Nov 20, 2015 at 15:23
  • @ChrisGeirman I wouldn't want to change the webpage itself as one can see it online. This would also just cause another problem on the webpage: How to put the header back in, without the user noticing it. Commented Nov 22, 2015 at 17:44
  • Yes it is - you can use the injectJavascript prop. facebook.github.io/react-native/docs/webview.html Commented Oct 31, 2017 at 3:07

4 Answers 4

8

I couldn't find a way to inject JavaScript or CSS before the page loads.

To workaround the flashing problem, I put another View on top of the WebView while it is still in loading state. The onNavigationStateChanged callback can be used to find out whether the page is loaded. The View I put on top simply shows an ActivityIndicatorIOS.

Sign up to request clarification or add additional context in comments.

Comments

1

My solution was this. As soon as the header loads, the interval catches it and removes it, then the interval destroys itself! Of course you can make the 250 even smaller if you still can glimpse it.

injectedJavaScriptBeforeContentLoaded ={`
    let myin = setInterval(()=>{
        let header = document.querySelector('header');
        if (header){
            header.remove();
            clearInterval(myin); 
        }
    },250)
    `}

Comments

0

I faced this issue, my solution was like that

render() {
    const remove_header = 'header = document.querySelector("header"); header.parentNode.removeChild(header);';
    uri = this.props.url
    return (
      <View style={{flex:1 }}>
        {(!this.state.showWebView) &&  <ActivityIndicator size="large" /> }
        <WebView
          style={this.state.showWebView ?  {flex:1} : {flex: 0} }
          source={{uri: uri}}
          javaScriptEnabled
          injectedJavaScript={'function injectRules() {'remove_header'};injectRules();'}
          onNavigationStateChange={(event) => {
            if (event.url !== uri) {
              this.webview.stopLoading()
              Linking.openURL(event.url)
            }
          }}
          onLoadStart={() => {
            this.setState({ showWebView: false })
          }}

          onLoadEnd={() => {
            if (!this.state.showWebView ) {
              this.setState({ showWebView: true })
            }
          }}
        />
      </View>
    )
  }

Comments

0

My quick solution was to add a negative marginTop to the WebView to hide the header. By doing this, the header is hidden before the render.

 webView: {
    ...
    marginTop: -80,
  },

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.