资讯专栏INFORMATION COLUMN

使用 qrcodejs 生成二维码的几个问题

Lyux / 1960人阅读

摘要:在这里的用法如下微信中多个二维码在一起识别错误这个问题,我也遇到了,根据网友的提示,微信是截屏识别的,所以会出现这种问题。示例代码这里代码跟前面脱节了,是另外的结构,仅作为示例代码是类似的一些的汇总对象微信中有两个挨着二维码长按识别的问题

博客地址

Preface

产品希望我这边下载页面加个二维码,可以扫描下载 APP,并且希望二维码中有公司的 logo,很合理的需求,不过实现的时候依旧遇到了几个问题,在此记录下。

Main

二维码的实现逻辑我当然没有这个时间去研究,直接用的 qrcodejs。官方给的 demo 是最简单的版本,各种各样的需求都是在 issues 里找到的提示,似乎这个库已经很久没有人去维护了,虽然 star 是很多。

官网示例(改编)
.qrcode {
  width: 150px;
  height: 150px;
  border: 2px solid green;
  margin-top: 15px;
}
let qrcodeEl = document.getElementById("qrcode")
let qrcode = new QRCode(qrcodeEl, {
  text: "https://avatars1.githubusercontent.com/u/23273077",
  width: 128,
  height: 128,
  colorDark: "#000000",
  colorLight: "#ffffff",
  correctLevel: QRCode.CorrectLevel.H
})

效果如图:

尺寸控制

我给官网的示例加上了边框,二维码的尺寸和 js 里的尺寸不一样,这个缺点立马就暴露出来了。

我很可能是想生成的二维码填满传入的 qrcode 元素的,但是这里的 width 不支持 100%,更不支持 vw 这种尺寸单位了。当然,我可以用 qrcode.offsetWidth 来解决这个问题,但是如果 qrcode 的尺寸后期会动态修改的话,那不还是会有问题么。

经 SO 的提示,发现了一个好方案,

.qrcode {
  width: 150px;
  height: 150px;
  border: 2px solid green;
  margin-top: 15px;
}
.qrcode canvas + img {
  width: 100%;
  height: 100%;
}

这样就可以了,不过仍然有个不足,就是二维码有失真。经测试,只有传入的尺寸和 qrcode 的尺寸一样时,才不会失真,所以传入的尺寸还是需要动态计算。

加 logo 的二维码

qrcodejs 并没有提供这个 API,issues 里有人给了 demo,其实就是在原有元素上覆盖一个 logo 就可以了,虽然遮盖了原有二维码的一部分,但是实测并不影响扫描。不过我没有进行大规模测试,可能会有一定的错误率。

.qrcode {
  width: 150px;
  height: 150px;
  border: 2px solid green;
  margin-top: 15px;
  position: relative;
}

.qrcode canvas + img {
  width: 100%;
  height: 100%;
}
.qrcode__logo {
  width: 50px;
  height: 50px;
  border-radius: 10%;
  border: 1px solid #fff;
  position: absolute;
  margin: auto;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}

效果如图:

检测二维码的生成

某些情况下,我需要重用二维码,在这种情况下,我发现,二维码的生成是异步的,譬如:

let qrcodeEl = document.getElementById("qrcode")
let qrcode = new QRCode(qrcodeEl, {
  text: "https://avatars1.githubusercontent.com/u/23273077",
  width: 200,
  height: 200,
  colorDark: "#000000",
  colorLight: "#ffffff",
  correctLevel: QRCode.CorrectLevel.H
})
let qrcodeImg = document.querySelectorAll(".qrcode canvas+img")
console.log("qrcodeImg.src", qrcodeImg.src)
setTimeout(function() {
  console.log("qrcodeImg.src", qrcodeImg.src)
}, 1000)

第一个日志就是空白的,第二个才有 base64。搞笑的是,qrcodejs 也没有给出回调或者通知告诉用户什么时候生成完毕。

这个问题也是在 issues 里找到的提示,关键点在于 MutationObserver。

这个 API 很少在项目中用,因为不兼容性 ie11-,但是有时在几千行代码里 debug 时会用,尤其是我怀疑中间有代码改了某个元素的属性,确又找不到证据或者找不到哪段代码时,会用这个来监测下。在这里的用法如下:

let qrcodeEl = document.getElementById("qrcode")
let qrcode = new QRCode(qrcodeEl, {
  text: "https://avatars1.githubusercontent.com/u/23273077",
  width: 200,
  height: 200,
  colorDark: "#000000",
  colorLight: "#ffffff",
  correctLevel: QRCode.CorrectLevel.H
})
let qrcodeImg = document.querySelector(".qrcode canvas+img")
listenQrcodeSrc()
function listenQrcodeSrc() {
  var observeConfig = { attributes: true }
  var observeCb = function(mutationsList, observer) {
    mutationsList.forEach(function(mutation) {
      if (
        mutation.type.toLowerCase() === "attributes" &&
        mutation.attributeName.toLowerCase() === "src"
      ) {
        console.log("qrcodeImg src done!", mutation.target.src)
        observer.disconnect()
      }
    })
  }
  if (typeof MutationObserver !== "undefined") {
    var observer = new MutationObserver(observeCb)
    observer.observe(qrcodeImg, observeConfig)
  }
}
微信中多个二维码在一起识别错误

这个问题,我也遇到了,根据网友的提示,微信是截屏识别的,所以会出现这种问题。我测试的结果是,左右两个,永远识别的右边的那个。网上有好几种方案:

调透明度和层级

最初尝试过,结果发现失败,等到成功的时候,透明度已经小于 0.5 了,视觉差异太明显,所以放弃了这个方案。

替换二维码

最终采取的是这个,这个也有问题,就是用户会看到二维码变化的过程,除非你把多个二维码做得很像。

假设,我们要显示两个二维码,所谓替换二维码,其实也就是在多个 img.src 属性里切换,可以把实际的二维码保存在 data-real-src 属性里,然后在用户 touchstart 事件中,替换另一个 imgsrc 为当前按下的这个,然后在 touchend 事件中再改回来,因为原来的地址都保存在 data-real-src 属性里。

这里就用到了前面提到的检测 src 属性来判断 qrcode 生成完毕,否则一开始直接把 src 属性赋给 data-real-src 属性,就是空白。

示例代码(这里代码跟前面脱节了,dom 是另外的结构,仅作为示例代码):

//* pubMethods 是类似 jq 的一些 API 的汇总对象
var qrcodeImgs = pubMethods.$(".download__qrcode-box canvas+img")
listenQrcodeSrc()
var downloadBox = pubMethods.$(".download")[0]
downloadBox.addEventListener("touchstart", changeQrcodeSrcToOne)
downloadBox.addEventListener("touchend", changeQrcodeSrcBack)
downloadBox.addEventListener("touchcancel", changeQrcodeSrcBack)

function listenQrcodeSrc() {
  var observeConfig = { attributes: true }
  var observeCb = function(mutationsList, observer) {
    mutationsList.forEach(function(mutation) {
      if (
        mutation.type.toLowerCase() === "attributes" &&
        mutation.attributeName.toLowerCase() === "src"
      ) {
        mutation.target.setAttribute("data-real-src", mutation.target.src)
        observer.disconnect()
      }
    })
  }
  qrcodeImgs.forEach(function(ele) {
    if (typeof MutationObserver !== "undefined") {
      var observer = new MutationObserver(observeCb)
      observer.observe(ele, observeConfig)
    }
  })
}
function changeQrcodeSrcToOne(event) {
  var target = event.target
  var getQrcodeBox = pubMethods.closest(
    target,
    ".download__qrcode-box",
    downloadBox
  )
  if (getQrcodeBox) {
    var targetImg = qrcodeImgs.filter(function(ele) {
      return getQrcodeBox.contains(ele)
    })[0]
    qrcodeImgs.forEach(function(ele) {
      ele.src = targetImg.getAttribute("data-real-src")
    })
  }
}
function changeQrcodeSrcBack(event) {
  qrcodeImgs.forEach(function(ele) {
    ele.src = ele.getAttribute("data-real-src")
  })
}
Ending Reference

Make qr code full width

微信中有两个挨着二维码长按识别的问题?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99324.html

相关文章

  • 使用JavaScript生成维码教程-附qrcodejs中文文档

    摘要:使用生成二维码依赖需要使用到的库至此一个简单的二维码就生成了接下来我们就详细了解一下这个库到底为我们提供了哪些参数配置和方法配置名称默认值类型说明显示二维码的元素或该元素的参数配置名称默认值类型说明需要生成的二维码内容图像宽度图像高度前 使用javascript生成二维码 依赖jquery 需要使用到的库 https://github.com/davidshimj... DIV j...

    oneasp 评论0 收藏0
  • vue 2.x项目 vue-qriously 生成维码并下载、cliploard复制粘贴

    摘要:近日,重构项目某一老模块时,有一个功能是生成二维码并下载,还可以复制链接。先想着新模块中是否有生成二维码的插件,看了下。项目中封装了一个指令。一份用来显示的。顺带说一下,复制粘贴复制粘贴老模块中是用的仓库。 近日,重构项目某一老模块时,有一个功能是生成二维码并下载,还可以复制链接。列表每项都有二维码、下载二维码和复制链接和列表上方总的二维码。老模块是用的qrocode中文文档,qrco...

    littlelightss 评论0 收藏0
  • 微信小程序生成维码工具

    摘要:微信小程序生成二维码工具生成二维码数据的主要代码来自,因为它这个里面生成二维码图片的功能在微信小程序里不能使用,我将这个功能改写成可以在微信小程序中使用。 weapp-qrcode 微信小程序生成二维码工具 生成二维码数据的主要代码来自davidshimjs/qrcodejs,因为它这个里面生成二维码图片的功能在微信小程序里不能使用,我将这个功能改写成可以在微信小程序中使用。 截图 s...

    Rocture 评论0 收藏0
  • 移动端h5开发相关内容总结(四)

    摘要:主要原因是除了安卓和系统的写法不同外,不同系统版本写法也不同。在安卓上是默认不开启想磁盘写文件的权限的。最好维护一个系统无法正常推起输入框的软件列表可以通过的来获取软件的唯一标识。 前言: 看了下博客的更新时间,发现9月份一篇也没有更新。一直想着都要抽时间写一篇的,不然今年的更新记录就会断在了9月份。但是还是应为各种各样的事情给耽搁了。当内心突然涌起一股必须写点什么的时候,突然发现自己...

    MAX_zuo 评论0 收藏0

发表评论

0条评论

Lyux

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<