做为一名开发者,你们应该都知道在浏览器中存在一些内置的控件:Alert,Confirm等,可是这些控件一般根据浏览器产商的不一样而形态万千,视觉效果每每达不到UI设计师的要求。更重要的是,这类内置控件的风格很难与形形色色的各类风格迥异的互联网产品的设计风格统一。所以,优秀的前端开发者们各自开发本身的个性化控件来替代浏览器内置的这些控件。固然,这类组件在网络上已经有不可胜数至关优秀的,写这篇文章的目的不是为了说明我开发的这个组件有多优秀,也不是为了炫耀什么,只是但愿经过这种方式,与更多的开发者互相交流,互相学习,共同进步。好,废话很少说,言归正传。css
一、Alert控件html
二、Confirm控件前端
首先,咱们来看下内置组件的基本使用方法:vue
1 alert("内置Alert控件"); 2 if (confirm("关闭内置Confirm控件?")) { 3 alert("True"); 4 } else { 5 alert("False"); 6 }
为了保证咱们的组件使用方式和内置控件保持一致,因此咱们必须考虑覆盖内置控件。考虑到组件开发的风格统一,易用,易维护,以及面向对象等特性,我计划将自定义的alert和confirm方法做为一个类(Winpop)的实例方法,最后用实例方法去覆盖系统内置控件的方法。为了达到目的,个人基本作法以下:node
1 var obj = new Winpop(); // 建立一个Winpop的实例对象 2 // 覆盖alert控件 3 window.alert = function(str) { 4 obj.alert.call(obj, str); 5 }; 6 // 覆盖confirm控件 7 window.confirm = function(str, cb) { 8 obj.confirm.call(obj, str, cb); 9 }; //在此我向你们推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提高思惟能力
须要注意的是,因为浏览器内置的控件能够阻止浏览器的其余行为,而咱们自定义的组件并不能具有这种能力,为了尽量的作到统一,正如预览图上看到的,咱们在弹出自定义组件的时候使用了一个全屏半透明遮罩层。也正是因为上述缘由,confirm组件的使用方式也作了一些细微的调整,由内置返回布尔值的方式,改成使用回调函数的方式,以确保能够正确的添加“肯定”和“取消”的逻辑。所以,自定义组件的使用方式就变成了下面这种形式:webpack
1 alert("自定义Alert组件"); 2 confirm("关闭自定义Confirm组件?", function(flag){ 3 if (flag) { 4 alert("True"); 5 } else { 6 alert("False"); 7 } //在此我向你们推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提高思惟能力 8 });
在正式介绍Winpop组件的代码以前,咱们先来看一下一个Javascript组件的基本结构:web
1 (function(window, undefined) { 2 function JsClassName(cfg) { 3 var config = cfg || {}; 4 this.get = function(n) { 5 return config[n]; 6 } 7 this.set = function(n, v) { 8 config[n] = v; 9 } 10 this.init(); 11 } 12 JsClassName.prototype = { 13 init: function(){}, 14 otherMethod: function(){} 15 }; //在此我向你们推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提高思惟能力 16 window.JsClassName = window.JsClassName || JsClassName; 17 })(window);
使用一个自执行的匿名函数将咱们的组件代码包裹起来,尽量的减小全局污染,最后再将咱们的类附到全局window对象上,这是一种比较推荐的作法。面试
构造函数中的get、set方法不是必须的,只是笔者的我的习惯而已,以为这样写能够将配置参数和其余组件内部全局变量缓存和读取的调用方式统一,彷佛也更具备面向对象的型。欢迎读者们说说各自的想法,说说这样写到底好很差。浏览器
本次给你们推荐一个免费的学习圈,里面归纳移动应用网站开发,css,html,webpack,vue node angular以及面试资源等。获取资料👈👈👈
对web开发技术感兴趣的同窗,欢迎加裙:👉👉👉582735936 👈👈👈,无论你是小白仍是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时天天更新视频资料。缓存
接下来咱们一块儿看下Winpop组件的完整代码:
1 (function(window, jQuery, undefined) { 2 3 var HTMLS = { 4 ovl: '<div id="J_WinpopMask"></div>' + '<div id="J_WinpopBox">' + '<div></div>' + '<div></div>' + '</div>', 5 alert: '<input type="button" value="肯定">', 6 confirm: '<input type="button" value="取消">' + '<input type="button" value="肯定">' 7 } 8 9 function Winpop() { 10 var config = {}; 11 this.get = function(n) { 12 return config[n]; 13 } 14 15 this.set = function(n, v) { 16 config[n] = v; 17 } 18 this.init(); 19 } //在此我向你们推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提高思惟能力 20 21 Winpop.prototype = { 22 init: function() { 23 this.createDom(); 24 this.bindEvent(); 25 }, 26 createDom: function() { 27 var body = jQuery("body"), 28 ovl = jQuery("#J_WinpopBox"); 29 30 if (ovl.length === 0) { 31 body.append(HTMLS.ovl); 32 } 33 34 this.set("ovl", jQuery("#J_WinpopBox")); 35 this.set("mask", jQuery("#J_WinpopMask")); 36 }, 37 bindEvent: function() { 38 var _this = this, 39 ovl = _this.get("ovl"), 40 mask = _this.get("mask"); 41 ovl.on("click", ".J_AltBtn", function(e) { 42 _this.hide(); 43 }); 44 ovl.on("click", ".J_CfmTrue", function(e) { 45 var cb = _this.get("confirmBack"); 46 _this.hide(); 47 cb && cb(true); 48 }); 49 ovl.on("click", ".J_CfmFalse", function(e) { 50 var cb = _this.get("confirmBack"); 51 _this.hide(); 52 cb && cb(false); 53 }); 54 mask.on("click", function(e) { 55 _this.hide(); 56 }); 57 jQuery(document).on("keyup", function(e) { 58 var kc = e.keyCode, 59 cb = _this.get("confirmBack");; 60 if (kc === 27) { 61 _this.hide(); 62 } else if (kc === 13) { 63 _this.hide(); 64 if (_this.get("type") === "confirm") { 65 cb && cb(true); 66 } 67 } 68 }); 69 }, 70 alert: function(str, btnstr) { 71 var str = typeof str === 'string' ? str : str.toString(), 72 ovl = this.get("ovl"); 73 this.set("type", "alert"); 74 ovl.find(".J_WinpopMain").html(str); 75 if (typeof btnstr == "undefined") { 76 ovl.find(".J_WinpopBtns").html(HTMLS.alert); 77 } else { 78 ovl.find(".J_WinpopBtns").html(btnstr); 79 } //在此我向你们推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提高思惟能力 80 this.show(); 81 }, 82 confirm: function(str, callback) { 83 var str = typeof str === 'string' ? str : str.toString(), 84 ovl = this.get("ovl"); 85 this.set("type", "confirm"); 86 ovl.find(".J_WinpopMain").html(str); 87 ovl.find(".J_WinpopBtns").html(HTMLS.confirm); 88 this.set("confirmBack", (callback || function() {})); 89 this.show(); 90 }, 91 show: function() { 92 this.get("ovl").show(); 93 this.get("mask").show(); 94 }, 95 hide: function() { 96 var ovl = this.get("ovl"); 97 ovl.find(".J_WinpopMain").html(""); 98 ovl.find(".J_WinpopBtns").html(""); 99 ovl.hide(); 100 this.get("mask").hide(); 101 }, 102 destory: function() { 103 this.get("ovl").remove(); 104 this.get("mask").remove(); 105 delete window.alert; 106 delete window.confirm; 107 } 108 }; 109 110 var obj = new Winpop(); 111 window.alert = function(str) { 112 obj.alert.call(obj, str); 113 }; 114 window.confirm = function(str, cb) { 115 obj.confirm.call(obj, str, cb); 116 }; 117 })(window, jQuery);
代码略多,关键作如下几点说明:
做为一个前端开发工程师,我的以为Javascript组件开发是一件颇有意思的事情,其中乐趣只有本身亲自动手尝试了才会体会获得。前端组件开发每每须要Javascript、CSS和html相互配合,才能事半功倍,上面提到的Winpop也不例外。
本次给你们推荐一个免费的学习圈,里面归纳移动应用网站开发,css,html,webpack,vue node angular以及面试资源等。获取资料👈👈👈
对web开发技术感兴趣的同窗,欢迎加裙:👉👉👉582735936 👈👈👈,无论你是小白仍是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时天天更新视频资料。最后,祝你们早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。