都说微信是移动端的IE6,不管你们信不信,反正我信了。最近在开发过程中就遇到了一个极其容易触发的BUG。
复现这个BUG只需要两个页面「a.html」以及「b.html」,并且两个页面都有跳去另一个页面的链接:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>A</title>
</head>
<body>
<h1>I am A.</h1>
<p><a href="b.html">to B</a></p>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>B</title>
</head>
<body>
<h1>I am B.</h1>
<p><a href="a.html">to A</a></p>
</body>
</html>
先打开「a.html」,点击链接跳转到「b.html」,再点击「b.html」中的链接跳转到「a.html」。如此往复点击跳转几次,就会出现无法再次跳转的情况(会出现进度条,但是无法跳转)。
这极有可能是微信在网页历史记录方面的BUG。然而,你并不能指望微信能很快地修复它,所以只能自己寻找解决方法。经过多次的尝试,我发现这个BUG在两种情况下不会触发:
- 页面上没有viewport的声明;
- 跳转的URL上带有问号(有问号就行了,不需要带参数)。
在移动端页面上,不声明viewport肯定是不可行的,所以只能考虑方法2。虽然说可以把链接改成这样:
<p><a href="a.html?">to A</a></p>
<p><a href="b.html?">to B</a></p>
但是实际项目中的链接非常多,一个一个地改很麻烦而且容易漏掉。这种情况用Javascript的事件代理模式来处理是比较合适的:
$('body').on('click', function(e) {
var target = e.target;
if (isAndroid && isInWX && target.tagName === 'A' && !target.search) {
// 只设为问号无效,所以还是得加个参数
// 其实很想换成另一个f开头的单词
target.search = '?fixwx';
}
});
这样做是有副作用的:页面跳转后URL就会带上了一个参数。如果你是个洁癖,不想URL不干净,也可以调用HTML 5的历史记录接口把它干掉:
var location = window.location;
if (location.search === '?fixwx') {
history.replaceState(
null,
document.title,
location.pathname + location.hash
);
}
最后必须提一下,这个方法并不能100%解决问题,因为有些跳转是用Javascript跳的,没有经过click事件。
评论 (5条)