web-dev-qa-db-fra.com

React native: Est-il possible d'avoir la hauteur d'un contenu HTML dans une vue Web?

Je reçois du contenu HTML d'une API et je veux le rendre sous forme de vue Web dans mon application.

Le composant webview est imbriqué dans un scrollview car il contient un autre contenu au-dessus de ma fonction de rendu:

render() {
      var html = '<!DOCTYPE html><html><body>' + this.state.pushEvent.Description + '</body></html>';

    return (
      <ScrollView>
        <View style={styles.recipe}>
          <Image source={{uri: this.state.pushEvent.ImageUrl}}
            style={styles.imgFull} />
          <Text style={styles.title}>{this.state.pushEvent.Title}</Text>
          
          <WebView style={{padding: 20}}
            automaticallyAdjustContentInsets={false}
            scrollEnabled={false}
            html={html}>
          </WebView>
        </View>
      </ScrollView>
    );
  }

Le problème est que mon html est juste 20 pt haut qui est mon remplissage. Existe-t-il un moyen intelligent d’obtenir la hauteur du contenu?

10
daniele bertella

Comme je l'ai écrit dans le commentaire ci-dessus, voici ce que j'ai écrit, mais je pense toujours qu'il devrait y avoir une meilleure solution.

Voici le numéro sur github dont je me suis inspiré: @hedgerwang answer

Dans mon var html, j'ai ajouté un script simple juste avant la balise body fermante. Je sauvegarde simplement la hauteur de mon html dans le titre de mon document:

<script>window.location.hash = 1;document.title = document.height;</script>

j'ai ensuite ajouté les propriétés onNavigationStateChange dans mon composant WebView avec un rappel qui définit une variable d'état "height", puis cette hauteur sur mon WebView. Comme je l'ai dit, cela a fait l'affaire, avec juste un peu de flahs lors de la modification du contenu de la WebView, mais je pense que c'est un sale bidouillage.

À la fin, j'ai décidé de changer l’API pour avoir quelque chose que je n’ai pas à inclure dans une WebView.

Mais peut-être que cela peut aider, voici le code complet.

onNavigationStateChange(navState) {
  this.setState({
    height: navState.title,
  });
}  
render() {
  var html = '<!DOCTYPE html><html><body>' + this.state.pushEvent.Description + '<script>window.location.hash = 1;document.title = document.height;</script></body></html>';
return (
  <ScrollView>
    <View style={styles.recipe}>
      <Image source={{uri: this.state.pushEvent.ImageUrl}}
        style={styles.imgFull} />
      <Text style={styles.title}>{this.state.pushEvent.Title}</Text>

      <WebView style={{padding: 20}}
        automaticallyAdjustContentInsets={false}
        scrollEnabled={false}
        onNavigationStateChange={this.onNavigationStateChange.bind(this)}
        html={html}>
      </WebView>
    </View>
  </ScrollView>
);
}
10
daniele bertella

Il existe un meilleur moyen de le faire: vous pouvez injecter du JS personnalisé avec la propriété injectedJavaScript . Le résultat de l'évaluation se retrouvera dans l'objet événement que vous recevez dans votre onNavigationStateChange . De cette façon, vous n'aurez pas à modifier le code HTML lui-même ni à pirater la propriété title.

Voir https://Gist.github.com/dbasedow/ed6e099823cb8d5ab30e pour un exemple.

9
Daniel Basedow

Le seul moyen fiable de le faire est via postMessage, dans le prop injectéJavascript (comme dans ce composant .

Passez document.scrollHeight et vous êtes tous ensemble.

const jsString = `
  function post () {
    postMessage(
      Math.max(document.documentElement.clientHeight, document.documentElement.scrollHeight, document.body.clientHeight, document.body.scrollHeight)
    );
  }
  setTimeout(post, 200);
// other custom js you may want
`


// component class:
  _onMessage = (e) => {
    this.setState({
      webviewHeight: parseInt(e.nativeEvent.data)
    });
  }
  render() {
    return (
      <WebView
        source={yourURL}

        injectedJavascript={jsString}
        onMessage={this._onMessage}

        style={{ height: webviewHeight }}
      />
    )
  }
0
kriskate

Ce composant a parfaitement fonctionné pour moi. Il ajuste la vue Web en fonction du contenu et renvoie la hauteur du code HTML rendu.

https://Gist.github.com/epeli/10c77c1710dd137a1335

Et changer

import React, {WebView, View, Text} from "react-native";

for

import React from "react";
import {WebView, View, Text} from "react-native";

en haut du fichier.

0
Agu Dondo