移动端 WebView 实现强制文本换行(类似于文本重排)
2021-06-11 本文已影响0人
天下第九九八十一
一些网页,由于并未适配移动端,或由于一些特别原因而无法使用(你懂的,插入横幅GIF广告、折叠一部分内容、要求跳转至APP等等),此时,请求得到的只能是桌面版网页。
桌面版网页在移动端上,由于字体太小、放大后又需要频繁地左右滚动,阅读起来十分困难。所以一些移动端的浏览器APP,比如Opera浏览器,都有强制文本换行的功能。
这个功能可以用JS实现,原理是为包含文本( text node, nodeType===3
)的元素节点加入最大宽度限制,动态地限制最大宽度为一计算值,此值为页面空间的窗口大小除以页面的缩放值。
但是,由于HTML标准里面没有定义页面缩放(zoom)的监听器,只有窗口大小变化(resize)的监听器,而且JS端(似乎)也无法获得页面的缩放值。所以单纯JS是不行的,必须结合客户端的代码。
先说说怎么限制最大宽度,JS代码示例,遍历限制所有文本容器的最大宽度为100px:
function traverseDom(p) {
var n = [];
n.push(p);
var cc = 1;
for(var j=0;j<cc;j++) {
p = n[j];
if(p.tagName!='A' && p.className.indexOf('code')<0) {
var m = p.childNodes, ln = m.length, pl = cc, i=0;
if(ln>p.childElementCount) {
for(;i<ln;i++) {
var e = m[i];
if(e.nodeType==3) {
var t=e.textContent;
if (/\S/.test(t) && t.length>8) {
cc = pl;
p.style.maxWidth = "100px";
//console.log(p);
break;
}
} else if(e.tagName!=undefined){
n.push(e);
cc++;
}
}
}
}
}
console.log("cc=", cc);
}
[].forEach.call(window.frames, function(e){
try{
traverseDom(window.frames[0].document.body);
} catch(e){}
});
traverseDom(document.body);
包含了iframe的处理,但无法处理跨域iframe。Opera浏览器可以强制跨域的iframe也自动折行,此处却不行。
如果是安卓平台,客户端的Java代码如下:
(WebViewClient)
public void onScaleChanged(WebView view, float oldScale,float newScale)
{
view.evaluateJavascript(WrappedOnResize+(view.getWidth()/newScale)+")", null);
}
字符串 WrappedOnResize :
强制文本换行(function(wd){
// 略,与先前的JS代码一致。
// 区别是要将其中的 100px 替换为 wd+"px"
})(
\