react-native-webview设置字体及高度设配
先来看一下效果图吧:(字体用的的思源宋体)
配置过程:
1.首页我用的是第三方的react-native-webview来加载页面的,当然react-native-autoheight-webview也是可以的
2.Webview部分的配置:
<WebView
ref={(webview) => {
this.web = webview
}}
onLoadEnd={this.onLoadEnd}//加载成功或者失败都会回调
originWhitelist={['*']}
source={{html: `你自己的html代码片段`, baseUrl: ''}}
injectedJavaScript={BaseScript}
onMessage={this.onMessage}
scrollEnabled={false}
decelerationRate='normal'
showsVerticalScrollIndicator={false}
textZoom={100}
javaScriptEnabled={true}
domStorageEnabled
scalesPageToFit
automaticallyAdjustContentInsets
style={{ flex: 0, height: this.state.height }}//html发送过来的内容高度,在onMessage中获取
>
</WebView>
有不明白具体属性是什么的可以去自己搜索一下。
说明:
*onMessage:接收html端传过来的信息(内容高度和一些自定义参数)
*BaseScript:注入html的js代码片段,往rn端发送参数
*自定义代码:这里是重点:建议在你的代码片段中一定要在外城嵌套html,mete,body标签,如果需要手动设置样式还可以加上 style标签,例如本文所说的字体就是用style来加载
- 首先meta定义缩放比例:
<meta name="viewport" content=width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
- 其次:
定义字体变量和字体路径变量:(前提是你需要把字体文件放到android/app/src/main/assets/fonts路径下)
let fontFamily = 'SourceHanSerifCN-Medium-6';
let fileFormat = 'ttf';
const fileName = Platform.select({
ios: `${fontFamily}.${fileFormat}`,
android: `file:///android_asset/fonts/SourceHanSerifCN-Medium-6.ttf`
})
Style中引入字体文件路径
<style type="text/css">
@font-face {
font-family: ${fontFamily};
src: url('${fileName}') format('${fileFormat === 'ttf' ? 'truetype' : 'opentype'}');
};
.title {
color: #313131;
font-size:18px;
line-height:22px;
font-family: SourceHanSerifCN-Medium-6;//这里需要注意一下
}
</style>
这里需要注意一下:如果在style中直接在某个class或者id添加font-family时(如上),有时候可能会出现加载页面白屏或者无法显示加载字体的问题,所以这里需要在BaseScript中重新定义一下字体
- BaseScript部分重新定义字体和其他样式:
const BaseScript =
`
document.getElementById('你的id').style.fontFamily="SourceHanSerifCN-Medium-6";
function changeHeight() {
if (document.body.scrollHeight != height) {
height = document.body.scrollHeight;
if (window.ReactNativeWebView) {
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'setHeight',
height: height
}))
}
}
}
setTimeout(changeHeight, 200);
//这里是监听rn端发送过来消息,用来处理一些在html中的操作(比如点击某个标签进行数据交
//换),不需要自行删去
window.document.addEventListener('message', function(e) {//注册事件 接收数据
const message = e.data;//字符串类型
height = document.body.scrollHeight;
if (window.ReactNativeWebView) {
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'setHeight',
height: height
}))
}
})
} ())
true;//注意:这是必需的,否则有时会出现故障
`
当然,这里我们一般会对某个class或者标签批量设置,这时用for循环来完成即可
- 最后,获取内容高度和内容显示问题(设置字体后出现的问题,如果没有设置字体内容显示是正常的):
这个对我来说问题很大,我用webview和autoheight-webview分别获取的高度是不同的,并且,我在用webview时在不同设备上获取的内容高度也所不同(同一篇文章在android5.x和6.x下获取高度时一样的,并且都能显示出来,在android10中获取的高度会有问题,并且不能显示全部的内容,如图:)
这部分确实让我很费心,其实方法很多,加点样式和高度就能出来,但是对于我的需求来说,每篇文章底部和下边图片的距离是固定的,不能改变,而且你不能保证每篇文章所加的高度和样式是一样的。
解决方法(很笨很麻烦但很管用):将webview下边的内容也加到html代码中,用webview来加载,这样我的问题完美解决(如果下边的内容很多的话是不是很麻烦呢!!!!)