前端QRCode.js生成二维码插件(解决长字符串显示模糊问题)

本文用于推荐一款很好用的二维码生成插件QRCode.js,测试使用方便且简单。
其实官方就有很好的文档,这里只是做一个我工作的记录和总结。

@version1.0——2018-11-22——创建《前端QRCode.js生成二维码插件》
@version1.1——2019-01-20——修改《前端QRCode.js生成二维码插件(解决长字符串显示模糊问题)》

  • 将注意事项提出不可忽略的问题
  • 添加长字符串显示模糊,手机二维码不能识别的问题
  • 添加解决小米8手机不显示二维码的问题

©burning_韵七七

  • 目录
    • 介绍
    • 使用
      • 1.引入js文件
      • 2.定义承载二维码标签
      • 3.js调用
      • 4.页面预览
    • 参数API
      • QRCode参数
      • Option参数
      • API接口
    • 实践
      • 生成二维码,微信QQ识别打开网页
    • 不可忽略的问题(踩坑)
      • url的中文编码问题
      • 长字符串的显示模糊问题
        • 问题分析
        • 解决思路
        • 实践真知
            1. 二维码难以识别
            1. 观察生成的结构
            1. 放大倍数
            1. css缩小倍数
            1. 解决小米8手机不显示二维码的问题
          • 此案例完整代码

介绍

  • 这个插件主要使用canvas实现的。
  • 原生代码不需要依赖jquery,或者zepto。
  • 兼容性也很好,IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, ETC.
  • 前端开发者仓库官网
  • GitHub地址

使用

1.引入js文件

<script src="qrcode.js"></script>

2.定义承载二维码标签

<div id="qrcode"></div>

3.js调用

简单调用

new QRCode(document.getElementById('qrcode'), 'your content');

设置参数调用

下面会有参数详解

var qrcode = new QRCode('qrcode', {
    text: 'your content',
    width: 256,
    height: 256,
    colorDark: '#000000',
    colorLight: '#ffffff',
    correctLevel: QRCode.CorrectLevel.H
});

4.页面预览

这样就很简单的生成了一个二维码


qrcode.jpg

参数API

QRCode参数

new QRCode(element, option)
名称 默认值 说明
element - 承载二维码的DOM元素的ID
option - 参数设置

Option参数

名称 默认值 说明 备注
text - 二维码承载的信息 如果是string那没有什么好说的。
如果是url的话,为了微信和QQ可以识别,连接中的中文使用encodeURIComponent进行编码
width 256 二维码宽度 单位像素(百分比不行)
height 256 二维码高度 单位像素(百分比不行)
colorDark '#000000' 二维码前景色 英文\十六进制\rgb\rgba\transparent都可以
colorLight '#ffffff' 二维码背景色 英文\十六进制\rgb\rgba\transparent都可以
correctLevel QRCode.CorrectLevel.L 容错级别 由低到高
QRCode.CorrectLevel.L
QRCode.CorrectLevel.M
QRCode.CorrectLevel.Q
QRCode.CorrectLevel.H

API接口

名称 参数 说明 使用
clear - 清除二维码 qrcode.clear()
makeCode string 替换二维码(参数里面是新的二维码内容) qrcode.makeCode('new content')
var qrcode = new QRCode('qrcode',{
    'text':'content',
    'width':256,
    'height':256,
    'colorDark':'red',
    'colorLoght':'transparent',
    'correctLevel':QRCode.CorrectLevel.H
})


qrcode.clear();
qrcode.madkCode('new content');

实践

生成二维码,微信QQ识别打开网页

需求

  • 前端根据传的不同的参数,在页面生成一个二维码
  • 由端分享到QQ、QQ空间、微信、朋友圈的时候,截屏成图片
  • 长按图片,识别其中的二维码,打开网页链接。

思路

  • 和端交互的网页a.html后面加query参数,如:http://www.test.html/a.html?code=123
  • a.html中调用QRCode.js生成一个二维码,二维码中的信息是http://www.test.html/b.html?code=123
  • 分享出去的页面是截屏是a.html的,识别图中的二维码打开b.html

实现

由于很简单,所以就不贴代码了。
但是下面有几个踩的坑,不可忽略的问题,必看。

不可忽略的问题(踩坑)

url的中文编码问题

如果传的是url,但是打开的时候只是一堆字符串让手动复制,那么说明url的地址不正确。
如果是微信,传的url的地址中有中文是可以识别的,但是在QQ中是不行的
所以其中的中文要进行encodeURIComponent编码,但是不要整体都编码,只是中文的部分编码即可。

长字符串的显示模糊问题

问题分析

显示模糊的问题,应该是canvas的问题。由于字符串比较长,尤其是需要传一个连接地址,后面还加一些参数的时候,就会加大二维码的像素复杂度,而本身canvas在绘制的时候,就一直有像素模糊的问题,尤其是在手机上的时候。

解决思路

所以可以利用这个问题,不动源码去解决因为长字符串导致的二维码模糊,手机无法识别的问题——先将生成的二维码进行倍数扩大,然后在css上面固定其显示宽高,这样就可以扩大显示像素精度。

实践真知

1. 二维码难以识别

下面二维码的识别难度:

  • QQ > weChat(相同长度的二维码,微信的识别程度比QQ的要好)
    • 微信中在大部分安卓手机上面是可以长按识别的,小部分安卓手机比如小米、oppo是无法识别的。还有苹果手机大部分也不能识别,更别说QQ了,所以这个问题需要解决。
cant1.png
2. 观察生成的结构

生成的页面结构可以看到是这样的。通过canvas生成二维码图片,然后canvas隐藏显示img。所以只要确保生成的canvas和img的宽高是100%即可。

生成的页面结构
3. 放大倍数
//显示二维码
var qrcode = new QRCode(document.getElementById("qrcodeConIn"), {
    text: `${location.origin}/codesearch/activity/broadcastgroup?requestAct=openview&openId=${data.openId}&random=${data.random}`,
    width: fontSize * 1.92 * 4,  //这里是根据rem进行了换算,后面的4指的就是四倍
    height: fontSize * 1.92 * 4, //这里是根据rem进行了换算,后面的4指的就是四倍
    colorDark : '#000',
    colorLight : "transparent",
    correctLevel : QRCode.CorrectLevel.H
});

看一下放大倍数的图片(为了效果展示的是3倍的图片)

3倍的二维码
4. css缩小倍数
/*固定宽高*/
.qrcodeCon{
    width: 2.2rem;
    height: 2.2rem;
    padding: 0.15rem;
}

/*内容自适应*/
.qrcodeConIn{
    width: 100%;
    height: 100%;
}

/*生成的二维码里面的img标签宽高自适应*/
.qrcodeConIn img{
    width: 100%;
    height: 100%;
}
/*一开始生成的canvas也要进行宽高自适应*/
.qrcodeConIn canvas{
    width: 100%;
    height: 100%;
}

这样就可以看到生成的效果了。
下面这个二维码,几乎所有手机的QQ和微信都可以识别了,如果还不能识别,那就继续加大倍数。

can1.png
5. 解决小米8手机不显示二维码的问题

先说我只是在测试的时候,发现小米8手机并不能生成二维码,我觉得肯定是有一些代码不兼容。但是目前没有时间去研究源码,留下一个坑。

但是是知道,小米8在生成二维码之后的img标签中的src为空
根据这个现象后面做了一个planB,待以后有时间研究了再完善。

//把代码放到事件队列后面
setTimeout(function(){
    //检测一下如果img标签里面的src没有base64就进行下面操作
    if(!$("#qrcodeConIn img").attr("src")){
        $("#qrcodeConIn img").show();
        $("#qrcodeConIn canvas").hide();
        var canvas = $("#qrcodeConIn canvas")[0];
        var dataURL = canvas.toDataURL("image/png");
        $("#qrcodeConIn img").attr("src",dataURL);
    }
},0);
此案例完整代码

html

<div class="codeCon">
    <!--撑开的后面背景-->
    <div class="inlineBlock qrcode">
        <!--白色部分占位-->
        <div id="qrcodeCon" class="qrcodeCon">
            <!--二维码显示范围-->
            <div id="qrcodeConIn" class="qrcodeConIn"></div>
        </div>
    </div>
    <div class="inlineBlock">
        <h3>长按识别</h3>
        <h3>扫码免费领</h3>
        <p>仅限今日</p>
    </div>
</div>

css

.codeCon{
    margin: 0 auto;
    width: 6.6rem;
    padding: 0.35rem 0;
    border-radius: 0.2rem;
    background-color: #eee;
}

.inlineBlock{
    display: inline-block;
    vertical-align: middle;
}
.qrcode{
    background-color: #fff;
    border-radius: 0.2rem;
    border: 1px solid #eee;
}
/*固定宽高*/
.qrcodeCon{
    width: 2.2rem;
    height: 2.2rem;
    padding: 0.15rem;
}

/*内容自适应*/
.qrcodeConIn{
    width: 100%;
    height: 100%;
}

h3{
    font-size: 0.4rem;
    margin-bottom: 0.15rem;
    letter-spacing: 0.04rem;
    text-indent: 0.04rem;
}
p{
    font-size: 0.32rem;
    letter-spacing: 0.2rem;
    text-indent: 0.2rem;
}

/*生成的二维码里面的img标签宽高自适应*/
.qrcodeConIn img{
    width: 100%;
    height: 100%;
}
/*一开始生成的canvas也要进行宽高自适应*/
.qrcodeConIn canvas{
    width: 100%;
    height: 100%;
}

js

//显示二维码
var qrcode = new QRCode(document.getElementById("qrcodeConIn"), {
    text: `${location.origin}/codesearch/activity/broadcastgroup?requestAct=openview&openId=${data.openId}&random=${data.random}`,
    width: fontSize * 1.92 * 4,
    height: fontSize * 1.92 * 4,
    colorDark : '#000',
    colorLight : "transparent",
    correctLevel : QRCode.CorrectLevel.H
});
setTimeout(function(){
    if(!$("#qrcodeConIn img").attr("src")){
        $("#qrcodeConIn img").show();
        $("#qrcodeConIn canvas").hide();
        var canvas = $("#qrcodeConIn canvas")[0];
        var dataURL = canvas.toDataURL("image/png");
        $("#qrcodeConIn img").attr("src",dataURL);
    }
},0);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    X先生_未知数的X阅读 15,965评论 3 119
  • 近年来随着企业所面临环境的不断变化,要求领导者要站出来,更多地根据环境的变化去做战略转型,让企业可以不断发展。 培...
    职场案例阅读 249评论 0 0
  • 内置数据结构(变量类型) list set dict tuple set(集合)- (一堆确定的无序的唯一数据) ...
    桃阿阅读 260评论 0 0
  • 发天纸的鞭炮声 响起灶老爷起驾的 人间烟火 膝盖便不由自主了 自编自导的供桌前 一头叩下 满地的沧桑 呜咽期许的悲...
    凹丁阅读 288评论 0 2
  • 岁月又逢冬,最恨离别时。“故关衰草遍,离别正堪悲。路出寒云外,人归暮雪时。少孤为客早,多难识君迟。掩泣空相向,风尘...
    向行阅读 2,791评论 4 7