引言
我們先來看這樣一段代碼
<divid="qrcode"ref="qrcode"class="bind-code-img"style="height: 180px;width: 180px;margin-top: 22px;display: none;
"></div>
new QRCode("qrcode", {width: 210,height: 210,text: this.qrcodeurl,correctLevel: QRCode.CorrectLevel.L,colorLight: "#ffffff",colorDark: "#000000",});
在項目開發中,我們使用 qrcode 插件將 url 轉換成二維碼,代碼邏輯在常規瀏覽器環境下運行良好,能正常生成可視化的二維碼圖片。然而,當部署到微信瀏覽器中時,卻出現了一個棘手的問題:用戶長按二維碼圖片,無法正常吊起微信的掃描彈窗,導致二維碼掃碼功能失效。這一問題嚴重影響了用戶通過掃碼跳轉鏈接的操作流程,比如無法實現掃碼關注公眾號、跳轉活動頁面等功能。
問題排查?
我們首先來看一下微信是如何識別頁面中的圖片并且調起彈窗的
- 檢測長按操作:微信客戶端會監測頁面中的?
img
?標簽,當用戶在?img
?標簽內進行長按操作時,客戶端會捕捉到這個動作。- 執行截屏操作:客戶端確認用戶長按?
img
?標簽后,會進行截屏。這里的截屏并非是對手機屏幕的真實截圖,而是基于 DOM(文檔對象模型),根據頁面上可用的信息構建出一個類似屏幕截圖的圖像數據。這樣做的好處是可以避免網絡傳輸等因素的影響,更快地獲取到用于識別的圖片數據,提升用戶體驗。- 啟動識別算法:截屏完成后,微信會啟動圖片識別算法對截屏圖像進行分析。對于二維碼圖片,微信有專門的二維碼識別算法,能夠快速準確地識別出二維碼中的信息,并執行相應的操作,如打開鏈接、顯示相關信息等。對于普通圖片,微信可能會根據圖像的特征、內容等進行分析,以提供相應的操作選項,如保存圖片、發送給朋友等。
那么問題找到了,是不是因為我們QRcode生成出來的圖片并不是img呢?
我們看運行到瀏覽器的代碼,來看一下qrcode實現二維碼的方式
創建 canvas 元素并設置 display 為 none 進行隱藏
將 canvas 中的二維碼圖像轉換為 base64 格式,創建 img 標簽并設置其 src 屬性為轉換后的 base64 數據
但在部分手機上,尤其是微信內置瀏覽器中,canvas 元素未能被完全隱藏,導致其仍覆蓋在 img 標簽上方。這就造成了交互問題:用戶長按二維碼時,瀏覽器實際響應的是不可見 canvas 的事件,而非我們期望的 img 標簽事件,最終使得微信無法觸發識別二維碼的功能。
解決方案
new QRCode("qrcode", {width: 210,height: 210,text: this.qrcodeurl,correctLevel: QRCode.CorrectLevel.L,colorLight: "#ffffff",colorDark: "#000000",
});
let qrcodeEle = document.getElementById("qrcode");
let cvs = qrcodeEle.querySelector("canvas");
this.qrcodeimg = cvs.toDataURL("image/png");
生成二維碼后,我們獲取當前容器下的canvas元素,將其轉換為base64編碼格式。接著隱藏原始二維碼生成容器,創建新的img元素并為其賦值。問題完美解決