我在React Native中有一个WebView来呈现一些html表。它适用于任何设备,但不适用于Motorola G5和G6手机。
我正在使用postMessage获取要在WebView上设置的表格高度。在那些摩托罗拉手机上,我在document.body.innerHTML
上渲染完整表格时,我的source={{ html: theHtmlStringContainingTheTable }}
(我也使用postMessage)为空。如果我只发送<h1>with some text on it</h1>
,则效果很好。
import React, { Component } from 'react';
import { WebView } from 'react-native';
import webviewFunctionGenerator from 'utils/webview-function-generator';
import format from 'format-number';
import { translate } from 'react-i18next';
import { groupBy, map, mapObjIndexed, propEq, compose, values, join } from 'ramda';
import { toKebabCase } from 'ramda-extension';
import chilled from './chilled';
import frozen from './frozen';
const currency = format({ round: 0 });
const renderCountry = (country) => {
const [name, abbr] = country.split('//');
return `<img class="flag" src="http://minerva-trade.mazzafc.tech/img/flags/${toKebabCase(name)}.png">${abbr}`;
};
const renderRows = compose(
join(''),
values,
mapObjIndexed(
(item, country) => `
<tr>
<td>
<div>
${renderCountry(country)}
</div>
</td>
<td class="values">${item.frozen ? currency(item.frozen.price) : '-'}</td>
<td class="values">${item.frozen ? currency(item.frozen.volume) : '-'}</td>
<td class="values">${item.chilled ? currency(item.chilled.price) : '-'}</td>
<td class="values">${item.chilled ? currency(item.chilled.volume) : '-'}</td>
</tr>
`,
),
);
const template = ({ countries, t }) => `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<style>
button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}
* {
line-height: 1;
font-weight: 400;
}
table {
width: 100%;
max-width: 100%;
font-family: Roboto, Helvetica, sans-serif;
border: 0;
text-align: center;
border-collapse: collapse;
table-layout: fixed;
}
table td, table th {
font-size: 12px;
border: 1px solid #F2F2F2;
padding: 5px 5px;
border-collapse: collapse;
background-color: #F8FAFA;
color: #565C63;
vertical-align: middle;
white-space: normal;
}
table tbody tr td {
text-align: right;
}
table tbody tr td:first-of-type {
text-align: center;
}
table tbody tr:nth-child(odd) td {
background-color: #FFF;
}
table tbody tr:nth-child(even) td {
background-color: #F8FAFA;
}
table td svg, table th svg {
width: 18px;
height: 18px;
margin-right: 5px;
}
table th span {
display: table-cell;
vertical-align: middle;
}
table th div,
table td div {
display: flex;
align-items: center;
justify-content: center;
}
.chilled {
color: #4A90E2;
}
.frozen {
color: #51B9D2;
}
.flag {
width: 18px;
height: 18px;
margin-right: 5px;
}
.values {
text-align: center;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th rowspan="2">${t.source}</th>
<th class="frozen" colspan="2">
<div>
${frozen}
${t.frozen}
</div>
</th>
<th class="chilled" colspan="2">
<div>
${chilled}
${t.chilled}
</div>
</th>
</tr>
<tr>
<td class="frozen">US$/ton.</td>
<td class="frozen">Ton</td>
<td class="chilled">US$/ton.</td>
<td class="chilled">Ton</td>
</tr>
</thead>
<tbody>
${renderRows(countries)}
</tbody>
</table>
</body>
</html>
`;
/* eslint-disable */
const injectableJs = webviewFunctionGenerator(function() {
setTimeout(() => {
const table = document.querySelector('table');
if (!table) {
window.postMessage(
JSON.stringify({
error: true,
message: 'Table does not exist!',
html: document.body.innerHTML,
}),
'*',
);
}
window.postMessage(
JSON.stringify({
tableHeight: table.clientHeight + 2,
html: document.body.innerHTML,
}),
'*',
);
}, 500);
});
/* eslint-enable */
class PricingTable extends Component {
state = { tableHeight: 0 };
handleMessage = ({ nativeEvent }) => {
const { error, message, tableHeight } = JSON.parse(nativeEvent.data);
console.log('--data--', JSON.parse(nativeEvent.data));
if (error) {
console.error(`[TABLE RENDERER] Error: ${message}`);
}
if (tableHeight) {
this.setState({ tableHeight });
}
};
render() {
const { t } = this.props;
const countries = map(
itens => ({
chilled: itens.find(propEq('availability', 'chilled')),
frozen: itens.find(propEq('availability', 'frozen')),
}),
groupBy(item => `${item.flag}//${item.country_abbreviation}`, this.props.pricings),
);
return (
<WebView
originWhitelist={['*']}
bounces={false}
scrollEnabled={false}
automaticallyAdjustContentInsets
injectedJavaScript={injectableJs}
onMessage={this.handleMessage}
style={{
width: '100%',
backgroundColor: 'transparent',
height: this.state.tableHeight || 250,
flex: 0,
}}
source={{
html: template({
countries,
t: {
chilled: t('common:chilled'),
frozen: t('common:frozen'),
source: t('common:source'),
},
}),
}}
/>
);
}
}
export default translate()(PricingTable);
答案 0 :(得分:0)
我有一个similar problem。为了解决这个问题,我指定了一个以像素为单位的高度,而不是默认的'auto'
或flex: 1
或width: '100%'
之类的默认值。我现在有一个类似的问题。
我怀疑建议是先停止使用Expo,然后再使用推荐的替代方法React Native Webview,然后再且仅当新的React Native才提交问题(Expo free / ejected)。 )应用与
存在相同的问题我怀疑这将是Facebook React Native团队的建议,因为WebView是deprecated,而新的替代版本React Native Webview只能与常规的React Native项目一起使用。如果尚不清楚,请阅读有关React Native和linking的信息。