React native: возможно ли иметь высоту содержимого html в веб-просмотре?

Я получаю html-контент из api, и я хочу отображать его как веб-представление в своем приложении.

Компонент webview вложен в scrollview, потому что у него есть другое содержимое над моей функцией рендеринга, это примерно так:

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

Ответ 1

Как я писал в комментарии выше, это то, с чем я вышел, но я все еще думаю, что должно быть лучшее решение.

Вот вопрос о github, на который я черпал вдохновение: ответ @hedgerwang

В моем var html я добавил простой script непосредственно перед закрывающим тегом body, я просто сохраняю высоту своего html в заголовке документа:

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

то я добавил реквизиты onNavigationStateChange в свой компонент WebView с обратным вызовом, который устанавливает переменную "высота", а затем устанавливает эту высоту для моего WebView. Как я уже сказал, это было трюк с небольшим flahsing при изменении содержимого в WebView, но я думаю, что это грязный хак.

В конце я решил изменить api, чтобы иметь что-то, что мне не нужно включать в WebView

Но, возможно, это может помочь, вот полный код.

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

Ответ 2

Существует лучший способ сделать это: вы можете добавить пользовательский JS с свойством injectedJavaScript. Результат оценки окажется в объекте события, который вы получите в onNavigationStateChange. Таким образом, вам не придется изменять сам HTML или убирать свойство title.

См. https://gist.github.com/dbasedow/ed6e099823cb8d5ab30e для примера

Ответ 3

Этот компонент отлично работал у меня. Он настраивает webview для соответствия содержимому и возвращает высоту отображаемого html.

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

И измените

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

для

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

в верхней части файла.