前面的話 在電腦端發現一篇好的博文,想在手機上訪問。這時,就必須打開手機瀏覽器輸入長長的URL地址才行,非常不方便。如果在博客標題的後面跟一張小的圖片,點擊該圖片後,出現一張二維碼的大圖,然後再通過手機掃一掃,來進行博文的訪問,就相對方便很多。 通過搜索引擎搜索了一些生成二維碼的文章,發現其並不是一 ...
前面的話
在電腦端發現一篇好的博文,想在手機上訪問。這時,就必須打開手機瀏覽器輸入長長的URL地址才行,非常不方便。如果在博客標題的後面跟一張小的圖片,點擊該圖片後,出現一張二維碼的大圖,然後再通過手機掃一掃,來進行博文的訪問,就相對方便很多。
通過搜索引擎搜索了一些生成二維碼的文章,發現其並不是一件容易的事。同時,也發現了qrcode插件,該插件專門用於生成二維碼。於是,在qrcode的基礎上,實現了一個二維碼插件qr
效果演示
如果細心的話,會發現該博文標題的後面緊跟著一個表示二維碼的手機小圖標。點擊該圖標後,出現二維碼大圖,通過手機掃一掃,即可進行手機端對網頁的訪問。再點擊小圖標或二維碼圖片後,二維碼圖片消失
我將該插件命名為qr.js,使用方式很簡單,只要進行如下引入既可
<script src="http://files.cnblogs.com/files/xiaohuochai/qr.js"></script>
原理說明
1、首先分析博客園的HTML結構
由上圖可知,博客園的博文位於類名為'post'的div中,外層是id名為'topics'的div,而博文的標題位於類名為'postTitle'的h1中。所以,當頁面結構載入完成後,就可以在該標題的後面添加圖片了
var oBox = document.getElementById('topics'); var oTitle = oBox.getElementsByTagName('h1')[0]; console.log(oTitle.innerHTML);
2、二維碼小圖生成
現在,需要準備一個二維碼小圖,插入博文標題後面
通過iconfont,找到一個二維碼小圖,該小圖如下所示,因為是為了方便移動端使用,所以使用了一個表示‘小手機’的圖標
然後將對該圖片進行base64編碼
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAoklEQVQ4T+2T4Q2CMBCFv27CBjgCG+gIjAAbOAIjOIJs4Ai6gRvIBpjXXCOp19T/8pJLoTneXcj3Ah91wAV4bu68xwXoAZ2EzEAmE9AWTB6AelRDyaAx9zgh0wE4ATczcTdIE7wl0oe7wX/8RMHigfQTB3fDdM1IEvYyONdIVEOSqDwCY2Z2NaS/UNbqMSQmvauUPlfbNKpBSdTUVyXSs/XyBlRCNBG20I28AAAAAElFTkSuQmCC
通過查看樣式,使用的皮膚對img標題設置了margin屬性,如下所示
所以,這裡需要對margin置0
var oBox = document.getElementById('topics'); var oTitle = oBox.getElementsByTagName('h1')[0]; var oImg = new Image(); oImg.id = 'oImg'; oImg.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAoklEQVQ4T+2T4Q2CMBCFv27CBjgCG+gIjAAbOAIjOIJs4Ai6gRvIBpjXXCOp19T/8pJLoTneXcj3Ah91wAV4bu68xwXoAZ2EzEAmE9AWTB6AelRDyaAx9zgh0wE4ATczcTdIE7wl0oe7wX/8RMHigfQTB3fDdM1IEvYyONdIVEOSqDwCY2Z2NaS/UNbqMSQmvauUPlfbNKpBSdTUVyXSs/XyBlRCNBG20I28AAAAAElFTkSuQmCC"; oImg.style.margin = '0'; oTitle.appendChild(oImg);
3、將該網頁的URL轉換為二維碼
獲取URL非常簡單,只要使用location對象的href屬性即可
接下來,就要使用QRCode插件來實現將URL轉換為二維碼的功能了,首先先下載qrcodejs插件,然後將博文的URL轉換為自定義尺寸的二維碼
<div id="qrcode"></div> <script src="http://files.cnblogs.com/files/xiaohuochai/qrcode.min.js"></script> <script type="text/javascript"> var qrcode = new QRCode(document.getElementById("qrcode"), { text: location.href, width: 80, height: 80 }); </script>
生成如下圖所示的二維碼圖片
4、動態生成及滑鼠點擊事件
由於最終是要封裝在一個js文件中的,所以第三步涉及到的HTML結構都需要動態生成
由於生成二維碼需要依賴qrcodejs插件,所以只要當該插件載入完畢後,才可以進行後續操作。script標簽支持load事件,但不相容IE8-瀏覽器。所以,更保險的方法是使用window.onload
滑鼠點擊標識圖片後,在標識圖片的右側顯示生成的二維碼圖片,由於該二維碼圖片要相當於圖片進行絕對定位,所以需要改變HTML結構,在小標識圖片的外層添加一層oImgBox的div,用於定位大的二維碼圖片
//獲取博文標題 var oBox = document.getElementById('topics'); var oTitle = oBox.getElementsByTagName('h1')[0]; //創建標識圖片及外層包裝div var oImgBox = document.createElement('div'); oImgBox.style.cssText = 'position:relative;display:inline-block;vertical-align:middle'; var oImg = new Image(); oImg.id = 'oImg'; oImg.style.cursor = 'pointer'; oImg.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAoklEQVQ4T+2T4Q2CMBCFv27CBjgCG+gIjAAbOAIjOIJs4Ai6gRvIBpjXXCOp19T/8pJLoTneXcj3Ah91wAV4bu68xwXoAZ2EzEAmE9AWTB6AelRDyaAx9zgh0wE4ATczcTdIE7wl0oe7wX/8RMHigfQTB3fDdM1IEvYyONdIVEOSqDwCY2Z2NaS/UNbqMSQmvauUPlfbNKpBSdTUVyXSs/XyBlRCNBG20I28AAAAAElFTkSuQmCC"; oImg.style.margin = '0'; oImgBox.appendChild(oImg); //將標識圖片插入標題後面 oTitle.appendChild(oImgBox); //動態生成script標簽,引入qrcode插件 var script = document.createElement("script"); script.type = "text/javascript"; script.src = 'http://files.cnblogs.com/files/xiaohuochai/qrcode.min.js'; document.body.appendChild(script); //動態生成div標簽,用於放置通過qrcode插件生成的二維碼大圖,預設隱藏顯示 var oDiv = document.createElement('div'); oDiv.id = 'qrcode'; oDiv.mark = false; oDiv.style.cssText = 'display:none;position:absolute;left:20px;top:-40px'; oImgBox.appendChild(oDiv); window.onload = function(){ new QRCode(oDiv, { text: location.href, width: 80, height: 80 }); } //滑鼠移入標識圖片外層oImgBox後,在該標識圖片的右側顯示二維碼圖片 oImgBox.onclick = function(){ //如果mark為真,說明二維碼圖片正在顯示,將其隱藏 if(oDiv.mark){ oDiv.style.display = 'none'; //否則說明二維碼圖片正在隱藏,將其顯示 }else{ oDiv.style.display = 'block'; } //將mark標識置反 oDiv.mark = !oDiv.mark; }
5、移動端優化
由於該功能只適用於電腦端,在移動端並無實際的用處。所以,可以通過用戶代理檢測,如果是非移動端,才執行上述操作
由於其他的插件也可能會用到window.onload,所以為了避免衝突,使用相容性的事件處理程式函數
優化後的最終代碼如下
(function(){ //事件處理程式相容寫法 function addEvent(target,type,handler){ if(target.addEventListener){ target.addEventListener(type,handler,false); }else{ target.attachEvent('on'+type,function(event){ return handler.call(target,event); }); } } function whichMobile(){ var ua = navigator.userAgent; if(/iPhone OS (\d+_\d+)/.test(ua)){ return 'iPhone' + RegExp.$1.replace("_","."); } if(/iPad.+OS (\d+_\d+)/.test(ua)){ return 'iPad' + RegExp.$1.replace("_",".") } if(/Android (\d+\.\d+)/.test(ua)){ return 'Android' + RegExp["$1"]; } } //如果是非移動端,則執行如下代碼 if(!whichMobile()){ //獲取博文標題 var oBox = document.getElementById('topics'); var oTitle = oBox.getElementsByTagName('h1')[0]; //創建標識圖片及外層包裝div var oImgBox = document.createElement('div'); oImgBox.style.cssText = 'position:relative;display:inline-block;vertical-align:middle'; var oImg = new Image(); oImg.id = 'oImg'; oImg.style.cursor = 'pointer'; oImg.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAoklEQVQ4T+2T4Q2CMBCFv27CBjgCG+gIjAAbOAIjOIJs4Ai6gRvIBpjXXCOp19T/8pJLoTneXcj3Ah91wAV4bu68xwXoAZ2EzEAmE9AWTB6AelRDyaAx9zgh0wE4ATczcTdIE7wl0oe7wX/8RMHigfQTB3fDdM1IEvYyONdIVEOSqDwCY2Z2NaS/UNbqMSQmvauUPlfbNKpBSdTUVyXSs/XyBlRCNBG20I28AAAAAElFTkSuQmCC"; oImg.style.margin = '0'; oImgBox.appendChild(oImg); //將標識圖片插入標題後面 oTitle.appendChild(oImgBox); //動態生成script標簽,引入qrcode插件 var script = document.createElement("script"); script.type = "text/javascript"; script.src = 'http://files.cnblogs.com/files/xiaohuochai/qrcode.min.js'; document.body.appendChild(script); //動態生成div標簽,用於放置通過qrcode插件生成的二維碼大圖,預設隱藏顯示 var oDiv = document.createElement('div'); oDiv.id = 'qrcode'; oDiv.mark = false; oDiv.style.cssText = 'display:none;position:absolute;left:20px;top:-40px'; oImgBox.appendChild(oDiv); addEvent(window,'load',function(){ new QRCode(oDiv, { text: location.href, width: 80, height: 80 }); }) //滑鼠移入標識圖片外層oImgBox後,在該標識圖片的右側顯示二維碼圖片 addEvent(oImgBox,'click',function(){ //如果mark為真,說明二維碼圖片正在顯示,將其隱藏 if(oDiv.mark){ oDiv.style.display = 'none'; //否則說明二維碼圖片正在隱藏,將其顯示 }else{ oDiv.style.display = 'block'; } //將mark標識置反 oDiv.mark = !oDiv.mark; }) } })();