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?
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>
);
}
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.
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 }}
/>
)
}
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.