在电脑端发现一篇好的博文,想在手机上访问。这时,就必须打开手机浏览器输入长长的 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 中。所以,当页面结构加载完成后,就可以在该标题的后面添加图片了
- varoBox = document.getElementById('topics');
- varoTitle = 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
- varoBox = document.getElementById('topics');
- varoTitle = oBox.getElementsByTagName('h1')[0];
- varoImg =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,用于定位大的二维码图片
- //获取博文标题
- varoBox = document.getElementById('topics');
- varoTitle = oBox.getElementsByTagName('h1')[0];
- //创建标识图片及外层包装div
- varoImgBox = document.createElement('div');
- oImgBox.style.CSSText = 'position:relative;display:inline-block;vertical-align:middle';
- varoImg =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插件
- varscript = document.createElement("script");
- script.type = "text/javascript";
- script.src = 'http://files.cnblogs.com/files/xiaohuochai/qrcode.min.js';
- document.body.appendChild(script);
- //动态生成div标签,用于放置通过qrcode插件生成的二维码大图,默认隐藏显示
- varoDiv = 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;
- })
- }
- })();
来源: http://www.cnblogs.com/xiaohuochai/p/6876551.html