微信大字模式下 web-view 页面排版错乱

大家好呀,我是晨光。新年开工两周了,这周发版,踩了个坑,微信大字体模式,打开我们的 h5 页面,发现整个页面的排版全乱了,而且老板可能会在大字模式下用这个页面来做演示,产品就很抓狂,所以压力就给到了开发。产品希望当天修复,所以就加了个晚班。本文给大家分享一下,这个坑爹问题


1、大字模式下,为什么会出现排版错乱?


为了保证不同屏幕尺寸上看到的效果一致,我们在代码中使用了等比缩放来计算元素的尺寸。大字模式下,可能因为浏览器对页面进行了自动缩放,而不是按照我们预期的等比缩放进行缩放,所以会出现排版错乱等。


2、怎么保证排版不乱?


微信设置了大字导致排版错乱,那我们可以重置下字体大小,让页面的排版恢复正常。


经过尝试发现,直接重置根字体,页面并不能直接生效,需要刷新一次,才会重置字体成功。下面是解决问题的代码,网上也有很多相似的解决办法。


function queryString(item) {
var sValue = location.search.match(new RegExp('[?&]' + item + '=([^&]*)(&?)', 'i'));
return sValue ? sValue[1] : sValue;
}

// 1、监听到微信设置字体的事件,就刷新页面
function handleFontSize() {
// 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', { fontSize: 2 });
// 重写设置网页字体大小的事件
WeixinJSBridge.on('menu:setfont', function() {
WeixinJSBridge.invoke('setFontSizeCallback', { fontSize: 2 });
if (!queryString('iswx_refresh')) {
// 2、通过修改 url 让页面刷新 一次
window.location.replace(location.href + '&iswx_refresh=111');
}
});
}


const u = navigator.userAgent;
const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;

// 只有在安卓下才会展示有问题,所以只在安卓场景下走进这段逻辑。
if (isAndroid) {
if (typeof WeixinJSBridge == 'object' && typeof WeixinJSBridge.invoke == 'function') {
handleFontSize();
} else {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', handleFontSize, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', handleFontSize);
document.attachEvent('onWeixinJSBridgeReady', handleFontSize);
}
}
}


3、为什么重刷一次排版才不会乱?


「在 CSS 中,字体大小是相对于父元素的。当页面加载时,浏览器会根据 CSS 样式表解析并渲染页面,包括计算和应用字体大小。如果在页面加载完成后再改变根节点 html 的字体大小,浏览器不会重新解析和渲染整个页面,而是保留之前计算的字体大小。」


我们使用 `rem` 作为元素单位时,需要知道 `rem` 单位是相对于根节点字体大小的,浏览器在计算 `rem` 单位的元素大小时,会使用根节点的字体大小作为参考。一旦元素的大小被计算和渲染完成,它的大小就不会再随着根节点字体大小的变化而自动调整。


所以如果要改变根节点 html 的字体大小,就需要刷新页面才能使新的字体大小生效。


4、当前页面重置字体后,为什么跳转到下一个页面字体也是重置之后的?


因为在同一个浏览器会话中,根节点的字体大小是全局共享的,会被所有页面所继承和使用。


当你在当前页面修改了根节点的字体大小后,下一个页面加载时会继承当前页面的字体大小设置。这是由于浏览器会话的特性,同一个浏览器会话中的页面共享一些全局设置,包括根节点的字体大小。


5、同一个浏览器会话


在Web浏览器中,一个浏览器会话(browser session)是指用户在打开浏览器开始浏览网页,到关闭浏览器结束浏览的整个过程。在这个过程中,用户在浏览器中打开的每个标签页或窗口都属于同一个浏览器会话。


具体来说,当用户在浏览器中打开一个新的标签页或窗口时,这个标签页或窗口会共享一些全局的浏览器设置和状态,包括浏览器的Cookie、缓存、会话存储(session storage)和根节点的样式等。这些共享的设置和状态使得用户在不同的标签页或窗口之间可以共享数据和状态。


对于小程序中的 web-view 组件来说,同一个浏览器会话中的不同页面也会共享一些全局的浏览器设置和状态,包括根节点的样式。所以当我在一个页面中修改了根节点的样式,其他在同一个 web-view 组件内打开的页面也会继承并使用修改后的样式。


6、总结


在微信大字模式下,页面布局错乱的问题,我们通过设置跟字体,并刷新页面的方式保证页面的排版恢复正常。


对于同一个浏览器会话的页面,第一次刷新之后,根节点的字体大小已经重置,所以跳转到下一个页面是使用我们重置后的字体大小进行计算和布局,因此就不需要再次刷新。


为了实现这个效果,我们往 url 中添加已刷新过的标识,比如某个固定参数 iswx_refresh=111,如果有该参数,就不进行刷新。并且在跳转时透传该参数。


以上,全文完,有收获就给我点个赞吧😊

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP