最近又手撕了一个难搞的bug,问题是这样的:在ios的微信上(vue单页面项目),用户长按一张图片(微信上长按下载图片到本地),然后点击其他地方,点着点着就发现一大片区域被选中了,惨不忍睹,部分截图如下:
这个问题我发现在我的ios手机上并没有问题,好像是部分ios的微信有问题,有点蛋疼。。
后来经过多方排查,大致找到了问题的根源:在出问题的ios手机上,长按图片进行复制的时候,会选中其他的地方,我们看下面的图片:
在我们正常的认知中,只有选中文字,才会出现蓝色的范围选择;但是在出bug的机器上,长按图片,也会出现这个蓝色的选择条。
如果你也是ios手机,也可以点击上面的链接测试一下,在微信中打开,长按图片,看是否会出现文字被选中的情况,如果出现了,那么恭喜你复现了这个bug。
解决方案一
刚开始想到的是user-select这个css属性,控制img不能被选择:
img{
-moz-user-select: none;
user-select: none;
-webkit-user-select: none;
}
奈何没有效果,因为被选中的是文字,这样写没有效果,最后试了多次,只能暴力解决:
*{
-moz-user-select: none;
user-select: none;
-webkit-user-select: none;
}
这样的方案显然不是很好的方案,因为这样文字也无法复制了。
来个demo感受下:
解决方案二
现在的主要问题是长按图片的时候,文字被选中了,我们就监测选中事件:selectchange,如果是点击图片的时候,出发了selectchange,那我们就将页面上的选中清除:
(function() {
var clearSelection = function() {
var select = window.getSelection();
try {
select.removeAllRanges ? select.removeAllRanges() : select.empty ? select.empty() : select.clear && select.clear()
} catch(b) {}
}
var needClear = false;
document.addEventListener("selectionchange", function(e) {
if(needClear) {
clearSelection();
}
});
document.body.addEventListener("touchstart", function(e) {
if(e.target.nodeName.toLowerCase() == 'img') {
needClear = true;
} else {
needClear = false;
}
});
})();
来个demo感受下: