在电脑端发现一篇好的博文,想在手机上访问。这时,就必须打开手机浏览器输入长长的URL地址才行,很是不方便。若是在博客标题的后面跟一张小的图片,点击该图片后,出现一张二维码的大图,而后再经过手机扫一扫,来进行博文的访问,就相对方便不少。javascript
经过搜索引擎搜索了一些生成二维码的文章,发现其并非一件容易的事。同时,也发现了qrcode插件,该插件专门用于生成二维码。因而,在qrcode的基础上,实现了一个二维码插件qrcss
若是细心的话,会发现该博文标题的后面紧跟着一个表示二维码的手机小图标。点击该图标后,出现二维码大图,经过手机扫一扫,便可进行手机端对网页的访问。再点击小图标或二维码图片后,二维码图片消失html
我将该插件命名为qr.js,使用方式很简单,只要进行以下引入既可java
<script src="http://files.cnblogs.com/files/xiaohuochai/qr.js"></script>
一、首先分析博客园的HTML结构git
由上图可知,博客园的博文位于类名为'post'的div中,外层是id名为'topics'的div,而博文的标题位于类名为'postTitle'的h1中。因此,当页面结构加载完成后,就能够在该标题的后面添加图片了github
var oBox = document.getElementById('topics'); var oTitle = oBox.getElementsByTagName('h1')[0]; console.log(oTitle.innerHTML);
二、二维码小图生成浏览器
如今,须要准备一个二维码小图,插入博文标题后面app
经过iconfont,找到一个二维码小图,该小图以下所示,由于是为了方便移动端使用,因此使用了一个表示‘小手机’的图标函数
而后将对该图片进行base64编码post
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);
三、将该网页的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>
生成以下图所示的二维码图片
四、动态生成及鼠标点击事件
因为最终是要封装在一个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; }
五、移动端优化
因为该功能只适用于电脑端,在移动端并没有实际的用处。因此,能够经过用户代理检测,若是是非移动端,才执行上述操做
因为其余的插件也可能会用到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; }) } })();