本文用于推薦一款很好用的二維碼生成插件QRCode.js,測試使用方便且簡單。
其實官方就有很好的文檔,這里只是做一個我工作的記錄和總結(jié)。
@version1.0——2018-11-22——創(chuàng)建《前端QRCode.js生成二維碼插件》
@version1.1——2019-01-20——修改《前端QRCode.js生成二維碼插件(解決長字符串顯示模糊問題)》
- 將注意事項提出不可忽略的問題
- 添加長字符串顯示模糊,手機(jī)二維碼不能識別的問題
- 添加解決小米8手機(jī)不顯示二維碼的問題
?burning_韻七七
- 目錄
- 介紹
- 使用
- 1.引入js文件
- 2.定義承載二維碼標(biāo)簽
- 3.js調(diào)用
- 4.頁面預(yù)覽
- 參數(shù)API
- QRCode參數(shù)
- Option參數(shù)
- API接口
- 實踐
- 生成二維碼,微信QQ識別打開網(wǎng)頁
- 不可忽略的問題(踩坑)
- url的中文編碼問題
- 長字符串的顯示模糊問題
- 問題分析
- 解決思路
- 實踐真知
- 二維碼難以識別
- 觀察生成的結(jié)構(gòu)
- 放大倍數(shù)
- css縮小倍數(shù)
- 解決小米8手機(jī)不顯示二維碼的問題
- 此案例完整代碼
介紹
- 這個插件主要使用canvas實現(xiàn)的。
- 原生代碼不需要依賴jquery,或者zepto。
- 兼容性也很好,IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, ETC.
- 前端開發(fā)者倉庫官網(wǎng)
- GitHub地址
使用
1.引入js文件
<script src="qrcode.js"></script>
2.定義承載二維碼標(biāo)簽
<div id="qrcode"></div>
3.js調(diào)用
簡單調(diào)用
new QRCode(document.getElementById('qrcode'), 'your content');
設(shè)置參數(shù)調(diào)用
下面會有參數(shù)詳解
var qrcode = new QRCode('qrcode', {
text: 'your content',
width: 256,
height: 256,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
});
4.頁面預(yù)覽
這樣就很簡單的生成了一個二維碼
參數(shù)API
QRCode參數(shù)
new QRCode(element, option)
名稱 | 默認(rèn)值 | 說明 |
---|---|---|
element | - | 承載二維碼的DOM元素的ID |
option | - | 參數(shù)設(shè)置 |
Option參數(shù)
名稱 | 默認(rèn)值 | 說明 | 備注 |
---|---|---|---|
text | - | 二維碼承載的信息 | 如果是string那沒有什么好說的。 如果是url的話,為了微信和QQ可以識別,連接中的中文使用encodeURIComponent進(jìn)行編碼 |
width | 256 | 二維碼寬度 | 單位像素(百分比不行) |
height | 256 | 二維碼高度 | 單位像素(百分比不行) |
colorDark | '#000000' | 二維碼前景色 | 英文\十六進(jìn)制\rgb\rgba\transparent都可以 |
colorLight | '#ffffff' | 二維碼背景色 | 英文\十六進(jìn)制\rgb\rgba\transparent都可以 |
correctLevel | QRCode.CorrectLevel.L | 容錯級別 | 由低到高 QRCode.CorrectLevel.L QRCode.CorrectLevel.M QRCode.CorrectLevel.Q QRCode.CorrectLevel.H |
API接口
名稱 | 參數(shù) | 說明 | 使用 |
---|---|---|---|
clear | - | 清除二維碼 | qrcode.clear() |
makeCode | string | 替換二維碼(參數(shù)里面是新的二維碼內(nèi)容) | 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識別打開網(wǎng)頁
需求
- 前端根據(jù)傳的不同的參數(shù),在頁面生成一個二維碼
- 由端分享到QQ、QQ空間、微信、朋友圈的時候,截屏成圖片
- 長按圖片,識別其中的二維碼,打開網(wǎng)頁鏈接。
思路
- 和端交互的網(wǎng)頁a.html后面加query參數(shù),如:
http://www.test.html/a.html?code=123
- a.html中調(diào)用QRCode.js生成一個二維碼,二維碼中的信息是
http://www.test.html/b.html?code=123
- 分享出去的頁面是截屏是a.html的,識別圖中的二維碼打開b.html
實現(xiàn)
由于很簡單,所以就不貼代碼了。
但是下面有幾個踩的坑,不可忽略的問題,必看。
不可忽略的問題(踩坑)
url的中文編碼問題
如果傳的是url,但是打開的時候只是一堆字符串讓手動復(fù)制,那么說明url的地址不正確。
如果是微信,傳的url的地址中有中文是可以識別的,但是在QQ中是不行的
所以其中的中文要進(jìn)行encodeURIComponent編碼,但是不要整體都編碼,只是中文的部分編碼即可。
長字符串的顯示模糊問題
問題分析
顯示模糊的問題,應(yīng)該是canvas的問題。由于字符串比較長,尤其是需要傳一個連接地址,后面還加一些參數(shù)的時候,就會加大二維碼的像素復(fù)雜度,而本身canvas在繪制的時候,就一直有像素模糊的問題,尤其是在手機(jī)上的時候。
解決思路
所以可以利用這個問題,不動源碼去解決因為長字符串導(dǎo)致的二維碼模糊,手機(jī)無法識別的問題——先將生成的二維碼進(jìn)行倍數(shù)擴(kuò)大,然后在css上面固定其顯示寬高,這樣就可以擴(kuò)大顯示像素精度。
實踐真知
1. 二維碼難以識別
下面二維碼的識別難度:
- QQ > weChat(相同長度的二維碼,微信的識別程度比QQ的要好)
- 微信中在大部分安卓手機(jī)上面是可以長按識別的,小部分安卓手機(jī)比如小米、oppo是無法識別的。還有蘋果手機(jī)大部分也不能識別,更別說QQ了,所以這個問題需要解決。
2. 觀察生成的結(jié)構(gòu)
生成的頁面結(jié)構(gòu)可以看到是這樣的。通過canvas生成二維碼圖片,然后canvas隱藏顯示img。所以只要確保生成的canvas和img的寬高是100%即可。
3. 放大倍數(shù)
//顯示二維碼
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, //這里是根據(jù)rem進(jìn)行了換算,后面的4指的就是四倍
height: fontSize * 1.92 * 4, //這里是根據(jù)rem進(jìn)行了換算,后面的4指的就是四倍
colorDark : '#000',
colorLight : "transparent",
correctLevel : QRCode.CorrectLevel.H
});
看一下放大倍數(shù)的圖片(為了效果展示的是3倍的圖片)
4. css縮小倍數(shù)
/*固定寬高*/
.qrcodeCon{
width: 2.2rem;
height: 2.2rem;
padding: 0.15rem;
}
/*內(nèi)容自適應(yīng)*/
.qrcodeConIn{
width: 100%;
height: 100%;
}
/*生成的二維碼里面的img標(biāo)簽寬高自適應(yīng)*/
.qrcodeConIn img{
width: 100%;
height: 100%;
}
/*一開始生成的canvas也要進(jìn)行寬高自適應(yīng)*/
.qrcodeConIn canvas{
width: 100%;
height: 100%;
}
這樣就可以看到生成的效果了。
下面這個二維碼,幾乎所有手機(jī)的QQ和微信都可以識別了,如果還不能識別,那就繼續(xù)加大倍數(shù)。
5. 解決小米8手機(jī)不顯示二維碼的問題
先說我只是在測試的時候,發(fā)現(xiàn)小米8手機(jī)并不能生成二維碼,我覺得肯定是有一些代碼不兼容。但是目前沒有時間去研究源碼,留下一個坑。
但是是知道,小米8在生成二維碼之后的img標(biāo)簽中的src為空。
根據(jù)這個現(xiàn)象后面做了一個planB,待以后有時間研究了再完善。
//把代碼放到事件隊列后面
setTimeout(function(){
//檢測一下如果img標(biāo)簽里面的src沒有base64就進(jìn)行下面操作
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>掃碼免費領(lǐng)</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;
}
/*內(nèi)容自適應(yīng)*/
.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標(biāo)簽寬高自適應(yīng)*/
.qrcodeConIn img{
width: 100%;
height: 100%;
}
/*一開始生成的canvas也要進(jìn)行寬高自適應(yīng)*/
.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);