gpt4 book ai didi

webview - React Native 自动高度 WebView 在 Android 上不起作用

转载 作者:行者123 更新时间:2023-12-01 11:27:43 24 4
gpt4 key购买 nike

我正在实现一个具有动态高度的 WebView。我发现解决方案在 iOS 上非常有效,但在 Android 上不起作用。该解决方案使用WV内部的JS将标题设置为内容高度的值。这是代码:

...
this.state = {webViewHeight: 0};
...
<WebView
source={{html: this.wrapWevViewHtml(this.state.content)}}
style={{width: Dimensions.get('window').width - 20, height: this.state.webViewHeight}}
scrollEnabled={false}
javaScriptEnabled={true}
injectedJavaScript="window.location.hash = 1;document.title = document.height;"
onNavigationStateChange={this.onWebViewNavigationStateChange.bind(this)}
/>
...
onWebViewNavigationStateChange(navState) {
// navState.title == height on iOS and html content on android
if (navState.title) {
this.setState({
webViewHeight: Number(navState.title)
});
}
}
...

但在 android 上,onWebViewNavigationStateChange 中标题的值等于页面内容。

我做错了什么?

最佳答案

我也被这个搞糊涂了。它确实有效,但很难调试为什么它不起作用,因为 Android 上的 React Native WebView 未启用 Chrome 远程调试。

我遇到了两个问题:

  1. 我注入(inject)到 Webview 的脚本包含一些单行注释,在 Android 上所有换行符都被删除(另一个错误?)。它导致了 WebView 中的语法错误。

  2. 第一次调用标题内容确实是 Webview 的全部内容。不知道为什么,但在后者调用它的高度。所以只处理这种情况。

这是我现在使用的代码,它适用于 Android 和 iOS 上的 React Native 0.22

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


const BODY_TAG_PATTERN = /\<\/ *body\>/;

// Do not add any comments to this! It will break line breaks will removed for
// some weird reason.
var script = `
;(function() {
var wrapper = document.createElement("div");
wrapper.id = "height-wrapper";
while (document.body.firstChild) {
wrapper.appendChild(document.body.firstChild);
}

document.body.appendChild(wrapper);

var i = 0;
function updateHeight() {
document.title = wrapper.clientHeight;
window.location.hash = ++i;
}
updateHeight();

window.addEventListener("load", function() {
updateHeight();
setTimeout(updateHeight, 1000);
});

window.addEventListener("resize", updateHeight);
}());
`;


const style = `
<style>
body, html, #height-wrapper {
margin: 0;
padding: 0;
}
#height-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
}
</style>
<script>
${script}
</script>
`;

const codeInject = (html) => html.replace(BODY_TAG_PATTERN, style + "</body>");


/**
* Wrapped Webview which automatically sets the height according to the
* content. Scrolling is always disabled. Required when the Webview is embedded
* into a ScrollView with other components.
*
* Inspired by this SO answer http://stackoverflow.com/a/33012545
* */
var WebViewAutoHeight = React.createClass({

propTypes: {
source: React.PropTypes.object.isRequired,
injectedJavaScript: React.PropTypes.string,
minHeight: React.PropTypes.number,
onNavigationStateChange: React.PropTypes.func,
style: WebView.propTypes.style,
},

getDefaultProps() {
return {minHeight: 100};
},

getInitialState() {
return {
realContentHeight: this.props.minHeight,
};
},

handleNavigationChange(navState) {
if (navState.title) {
const realContentHeight = parseInt(navState.title, 10) || 0; // turn NaN to 0
this.setState({realContentHeight});
}
if (typeof this.props.onNavigationStateChange === "function") {
this.props.onNavigationStateChange(navState);
}
},

render() {
const {source, style, minHeight, ...otherProps} = this.props;
const html = source.html;

if (!html) {
throw new Error("WebViewAutoHeight supports only source.html");
}

if (!BODY_TAG_PATTERN.test(html)) {
throw new Error("Cannot find </body> from: " + html);
}

return (
<View>
<WebView
{...otherProps}
source={{html: codeInject(html)}}
scrollEnabled={false}
style={[style, {height: Math.max(this.state.realContentHeight, minHeight)}]}
javaScriptEnabled
onNavigationStateChange={this.handleNavigationChange}
/>
{process.env.NODE_ENV !== "production" &&
<Text>Web content height: {this.state.realContentHeight}</Text>}
</View>
);
},

});


export default WebViewAutoHeight;

作为要点 https://gist.github.com/epeli/10c77c1710dd137a1335

关于webview - React Native 自动高度 WebView 在 Android 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36053957/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com