问题:在微信浏览器内,页面中嵌套iframe,iframe中用户触发事件后有个弹框会显示二维码,用户长按二维码可以识别并跳转。尝试了一下,安卓是正常的,但是ios是识别不了的。
解决过程:
1.这里客户给的并不是一个二维码的图片地址,而是需要跳转的地址。首先需要先把跳转地址生成二维码。
这里用的是qrcode.js
html:作为生成二维码的容器
<div id="autoCode"></div>
js:这里需要引入qrcode.js.
我这里放在静态文件里,大家测试的时候可以使用,自己项目还是要提取出去使用。
$('#autoCode').qrcode({ width: 120, height: 120, text: `${res.domainname}` }); // 生成二维码
自定义宽度和高度,text : 生成的二维码需要跳转的地址。还可以自定义更多的样式,颜色之类的,有兴趣的可以查一下资料。
现在页面中就可以生成二维码了,手机可以扫描跳转,但是在移动端,长按二维码时,并没有任何用处,接下来解决长按识别问题。
2.将生成的二维码转化成img。
通过qrcode生成的二维码,其实是用canvas绘制的,所以客户端长按并不能识别,所以需要自己将二维码转化成图片。
var mycanvas1=document.getElementsByTagName('canvas')[0]; // 获取canvas生成的图像,转化为img
var img=convertCanvasToImage(mycanvas1); /**
* 将生成的canvas 提取图片
*/
function convertCanvasToImage(canvas) {
//新Image对象,可以理解为DOM
var image = new Image();
// canvas.toDataURL 返回的是一串Base64编码的URL,当然,浏览器自己肯定支持
// 指定格式 PNG
image.src = canvas.toDataURL("image/png");
return image;
}
这个时候以为大功告成了,试了一下安卓,可以长按识别跳转了,但是坑人的ios又不可以。
3.解决ios长按识别不了问题
问题原因:微信内ios识别二维码不准确,位置会有偏差,所能识别的区域页可能比当前二维码大小要小,导致用户按的位置并不一定可以识别。
解决方案:
①.在用户触摸到二维码时,生成一个图片,这个一定要是直接在body下,不要嵌套在别的结构里。
②.触摸二维码时,给生成的img设置src,img的大小控制好,覆盖用户可能触摸到的位置。
③.img可能会影响到布局,这里要设置img的透明度,再利用定位,可以达到不影响布局的情况下,实现效果。这里要注意的是,千万别设置display:none,要设置opcity。
④.当触摸结束时,将img隐藏。
上代码:
/**
* 给index传图片地址
*/
function sendImgSrc (url) {
$('.codeImg').on('touchstart', function () {
window.parent.postMessage(JSON.stringify({ status: 1, url: `${url}`}), '*')
}).on('touchend', function () {
window.parent.postMessage(JSON.stringify({ status: 2 }), '*')
})
}
因为我的页面是在iframe加载的,所以我需要将图片地址传给他的parent去处理触摸时生成的图片。
看一下父页面处理
// 解决iframe内二维码ios无法识别
window.addEventListener('message', function (e) {
var data = JSON.parse(e.data)
if (data.status == 1) {
$('.erweimaclass').css('z-index', 3)
$('.erweimaclass').attr('src', data.url).show();
} else if (data.status == 2){
$('.erweimaclass').css('z-index', '1')
$('.erweimaclass').hide();
} else if (data.status == 3) {
$('.erweimaclass').css('z-index', '1')
$('.erweimaclass').hide();
}
})
这样就可以控制图片的显示和隐藏了。再尝试,ios页可以正常识别和跳转了,如果你还不能识别,那你需要去调整你body下面的img的大小和位置,让用户触摸二维码时,区域被覆盖。