React本机自动高度WebView不';我不能在安卓上工作
我正在实现一个动态高度的WebView。我发现这个解决方案在iOS上很有魅力,但在android上却不起作用。该解决方案在WV中使用JS将标题设置为内容高度的值。代码如下:React本机自动高度WebView不';我不能在安卓上工作,webview,android-webview,react-native,Webview,Android Webview,React Native,我正在实现一个动态高度的WebView。我发现这个解决方案在iOS上很有魅力,但在android上却不起作用。该解决方案在WV中使用JS将标题设置为内容高度的值。代码如下: ... this.state = {webViewHeight: 0}; ... <WebView source={{html: this.wrapWevViewHtml(this.state.content)}} style={{width: Dimensions.get('window').widt
...
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)
});
}
}
...
。。。
this.state={webViewHeight:0};
...
...
onWebViewNavigationStateChange(导航状态){
//navState.title==iOS上的高度和android上的html内容
if(导航状态标题){
这是我的国家({
webViewHeight:编号(navState.title)
});
}
}
...
但是在android上,WebViewNavigationStateChange中的标题值等于页面内容
我做错了什么?我也被这件事弄糊涂了。它实际上可以工作,但很难调试为什么不能工作,因为Android上的React原生WebView没有启用Chrome远程调试 我对此有两个问题:
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;
import React,{WebView,View,Text}来自“React native”;
const BODY_TAG_PATTERN=/\/;
//不要对此添加任何评论!它将断开换行符将被删除
//一些奇怪的原因。
变量脚本=`
;(功能(){
var wrapper=document.createElement(“div”);
wrapper.id=“高度包装”;
while(document.body.firstChild){
appendChild(document.body.firstChild);
}
document.body.appendChild(包装器);
var i=0;
函数updateHeight(){
document.title=wrapper.clientHeight;
window.location.hash=++i;
}
updateHeight();
addEventListener(“加载”,函数(){
updateHeight();
setTimeout(updateHeight,1000);
});
addEventListener(“调整大小”,更新高度);
}());
`;
常量样式=`
正文,html,#高度包装{
保证金:0;
填充:0;
}
#高度包装{
位置:绝对位置;
排名:0;
左:0;
右:0;
}
${script}
`;
constcodeinject=(html)=>html.replace(BODY_-TAG_-PATTERN,style+);
/**
*Wrapped Webview,可根据
*内容。滚动始终处于禁用状态。嵌入Webview时需要
*与其他组件一起进入滚动视图。
*
*受到这个答案的启发http://stackoverflow.com/a/33012545
* */
var WebViewAutoHeight=React.createClass({
道具类型:{
来源:React.PropTypes.object.isRequired,
injectedJavaScript:React.PropTypes.string,
最小高度:React.PropTypes.number,
onNavigationStateChange:React.PropTypes.func,
样式:WebView.propTypes.style,
},
getDefaultProps(){
返回{minHeight:100};
},
getInitialState(){
返回{
realContentHeight:this.props.minHeight,
};
},
handleNavigationChange(导航状态){
if(导航状态标题){
const realContentHeight=parseInt(navState.title,10)| | 0;//将NaN变为0
this.setState({realContentHeight});
}
if(this.props.onNavigationStateChange==“函数”的类型){
this.props.onNavigationStateChange(navState);
}
},
render(){
const{source,style,minHeight,…otherProps}=this.props;
const html=source.html;
如果(!html){
抛出新错误(“WebViewAutoHeight仅支持source.html”);
}
如果(!BODY_TAG_PATTERN.test(html)){
抛出新错误(“无法从“+html”中找到);
}
返回(
{process.env.NODE_env!==“生产”&&
Web内容高度:{this.state.realContentHeight}
);
},
});
导出默认WebViewAutoHeight;
正如gist所示,在设备上加载本地HTML文件并注入JS是我在Android中找到的唯一正确设置标题/哈希的方法
/app/src/main/assets/blank.html
<!doctype html>
<html>
<head>
<title id="title">Go Web!</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
</style>
</head>
<body>
<div id="content"></div>
<script>
var content = document.getElementById('content');
var fireEvent = function(event, data) {
document.title = data;
window.location.hash = event;
};
var setContent = function(html) {
content.innerHTML = html;
};
</script>
</body>
</html>
上网!
var content=document.getElementById('content');
var firevent=函数(事件、数据){
document.title=数据;
window.location.hash=事件;
};
var setContent=函数(html){
content.innerHTML=html;
};
以及组件
class ResizingWebView extends Component {
constructor(props) {
super(props)
this.state = {
height: 0
}
}
onNavigationStateChange(navState) {
var event = navState.url.split('#')[1]
var data = navState.title
console.log(event, data)
if (event == 'resize') {
this.setState({ height: data })
}
}
render() {
var scripts = "setContent('<h1>Yay!</h1>');fireEvent('resize', '300')";
return (
<WebView
source={{ uri: 'file:///android_asset/blank.html' }}
injectedJavaScript={ scripts }
scalesPageToFit={ false }
style={{ height: this.state.height }}
onNavigationStateChange={ this.onNavigationStateChange.bind(this) }
/>
)
}
}
类大小调整WebView扩展组件{
建造师(道具){
超级(道具)
此.state={
身高:0
}
}
onNavigationStateChange(导航状态){
var event=navState.url.split(“#”)[1]
var data=navState.title
console.log(事件、数据)
如果(事件==“调整大小”){
this.setState({height:data})
}
}
render(){
var scripts=“setContent('Yay!');firevent('resize','300');
返回(
)
}
}
如果你想知道为什么你的代码不能在Android上运行,我会用下面的评论: