首页 > 代码库 > 改造一个JS插件的过程记录
改造一个JS插件的过程记录
最近做一个合作项目,对方要求我们做一个web应用程序,然后嵌入到他们的总的wen应用中,风格要求保持一致,于是乎就发了一个html文件过来,大概列举了一下各种控件,对话框的效果。
好了,重点说其中的一个弹出插件,其源码为:
(function($) { $(‘a[data-reveal-id]‘).live(‘click‘, function(e) { e.preventDefault(); var modalLocation = $(this).attr(‘data-reveal-id‘); $(‘#‘+modalLocation).reveal($(this).data()); }); $.fn.reveal = function(options) { var defaults = { animation: ‘fade‘, //fade, fadeAndPop, none animationspeed: 300, //how fast animtions are animationopacity:0.6,// BG opacity closeonbackgroundclick: true, //if you click background will modal close? dismissmodalclass: ‘close-reveal-modal‘, //the class of a button or element that will close an open modal }; var options = $.extend({}, defaults, options); return this.each(function() { /*--------------------------- Global Variables----------------------------*/ var modal = $(this), topMeasure = parseInt(modal.css(‘top‘)), topOffset = modal.height() + topMeasure, locked = false, modalBG = $(‘.reveal-modal-bg‘);/*--------------------------- Create Modal BG----------------------------*/ if(modalBG.length == 0) { modalBG = $(‘<div class="reveal-modal-bg" />‘).insertAfter(modal); } /*--------------------------- Open and add Closing Listeners----------------------------*/ //Open Modal Immediately openModal(); //Close Modal Listeners var closeButton = $(‘.‘ + options.dismissmodalclass).bind(‘click.modalEvent‘,closeModal) if(options.closeonbackgroundclick) { modalBG.css({"cursor":"pointer"}) modalBG.bind(‘click.modalEvent‘,closeModal) } /*--------------------------- Open & Close Animations----------------------------*/ //Entrance Animations function openModal() { modalBG.unbind(‘click.modalEvent‘); $(‘.‘ + options.dismissmodalclass).unbind(‘click.modalEvent‘); if(!locked) { lockModal(); if(options.animation == "fadeAndPop") { modal.css({‘top‘: $(document).scrollTop()-topOffset, ‘opacity‘ : 0, ‘visibility‘ : ‘visible‘}); modalBG.fadeIn(options.animationspeed/2); modal.delay(options.animationspeed/2).animate({ "top": $(document).scrollTop()+topMeasure, "opacity" : 1 }, options.animationspeed,unlockModal()); } if(options.animation == "fade") { modal.css({‘opacity‘ : 0, ‘visibility‘ : ‘visible‘, ‘top‘: $(document).scrollTop()+topMeasure}); modalBG.fadeIn(options.animationspeed/2, function(){ $(this).css(‘opacity‘,options.animationopacity); }); modal.delay(options.animationspeed/2).animate({ "opacity" : 1 }, options.animationspeed,unlockModal()); } if(options.animation == "none") { modal.css({‘visibility‘ : ‘visible‘, ‘top‘:$(document).scrollTop()+topMeasure}); modalBG.css({"display":"block"}); unlockModal() } } } //Closing Animation function closeModal() { if(!locked) { lockModal(); if(options.animation == "fadeAndPop") { modalBG.delay(options.animationspeed).fadeOut(options.animationspeed); modal.animate({ "top": $(document).scrollTop()-topOffset, "opacity" : 0 }, options.animationspeed/2, function() { modal.css({‘top‘:topMeasure, ‘opacity‘ : 1, ‘visibility‘ : ‘hidden‘}); unlockModal(); }); } if(options.animation == "fade") { modalBG.delay(options.animationspeed).fadeOut(options.animationspeed); modal.animate({ "opacity" : 0 }, options.animationspeed, function() { modal.css({‘opacity‘ : 1, ‘visibility‘ : ‘hidden‘, ‘top‘ : topMeasure}); unlockModal(); }); } if(options.animation == "none") { modal.css({‘visibility‘ : ‘hidden‘, ‘top‘ : topMeasure}); modalBG.css({‘display‘ : ‘none‘}); } } } /*--------------------------- Animations Locks----------------------------*/ function unlockModal() { locked = false; } function lockModal() { locked = true; } }); }})(jQuery);
这个插件的内容就是很简单,你写好如下的HTML,他就弹出一个提示请等待的Modal框,因为是JQuery的插件,所以调用方法其实就一句话:
$Obj.reveal()
其中,$Obj 是一个Jquery对象。这个模态框弹出之后,你点击之后就会关掉。(这个插件依赖Jqeury库,用的朋友你们懂的)
问题来了:这个拓展插件根本没提供程序关闭的方法有木有??难道只能手动点击才能关掉么?
忍不了这破东西,要不是对方规定好了效果,我非得重新弄一个不可。看来,得挽起袖子重写一下了。嗯。
我的基本思路就是,将这个JQuery插件改写为直接用面向对象的方法调用,可以直接关闭的插件,因为这个插件用了太多闭包,看样子改写的幅度还蛮大。
首先引入甘露模型:
/* File Created: 七月 23, 2014 */function Class() { var aDefine = arguments[arguments.length - 1]; //最后一个参数是类定义 if (!aDefine) return; var aBase = arguments.length > 1 ? arguments[0] : object; //解析基类 function prototype_() { }; //构造prototype的临时函数,用于挂接原型链 prototype_.prototype = aBase.prototype; //准备传递prototype var aPrototype = new prototype_(); //建立类要用的prototype for (var member in aDefine) //复制类定义到当前类的prototype if (member != "Create") //构造函数不用复制 aPrototype[member] = aDefine[member]; //根据是否继承特殊属性和性能情况,可分别注释掉下列的语句 if (aDefine.toString != Object.prototype.toString) aPrototype.toString = aDefine.toString; if (aDefine.toLocaleString != Object.prototype.toLocaleString) aPrototype.toLocaleString = aDefine.toLocaleString; if (aDefine.valueOf != Object.prototype.valueOf) aPrototype.valueOf = aDefine.valueOf; if (aDefine.Create) //若有构造函数 var aType = aDefine.Create //类型即为该构造函数 else //否则为默认构造函数 aType = function () { this.base.apply(this, arguments); //调用基类构造函数 }; aType.prototype = aPrototype; //设置类(构造函数)的prototype aType.Base = aBase; //设置类型关系,便于追溯继承关系 aType.prototype.Type = aType; //为本类对象扩展一个Type属性 return aType; //返回构造函数作为类};//根类object定义:function object() { } //定义小写的object根类,用于实现最基础的方法等object.prototype.isA = function (aType) //判断对象是否属于某类型{ var self = this.Type; while (self) { if (self == aType) return true; self = self.Base; }; return false;};object.prototype.base = function () //调用基类构造函数{ var Base = this.Type.Base; //获取当前对象的基类 if (!Base.Base) //若基类已没有基类 Base.apply(this, arguments) //则直接调用基类构造函数 else //若基类还有基类 { this.base = MakeBase(Base); //先覆写this.base Base.apply(this, arguments); //再调用基类构造函数 delete this.base; //删除覆写的base属性 }; function MakeBase(Type) //包装基类构造函数 { var Base = Type.Base; if (!Base.Base) return Base; //基类已无基类,就无需包装 return function () //包装为引用临时变量Base的闭包函数 { this.base = MakeBase(Base); //先覆写this.base Base.apply(this, arguments); //再调用基类构造函数 }; };};
O了,这一段如果有不明白的地方,必须得看《悟透Javascript这本书了》 我这里篇幅有限,不多介绍了。
接下来,写下自己已经改造好了的插件
/* File Created: 七月 23, 2014 */var CustomerModal = Class({ openModal: function () { modalBG.unbind(‘click.modalEvent‘); $(‘.‘ + this.options.dismissmodalclass).unbind(‘click.modalEvent‘); if (!locked) { this.lockModal(); if (this.options.animation == "fadeAndPop") { modal.css({ ‘top‘: $(document).scrollTop() - topOffset, ‘opacity‘: 0, ‘visibility‘: ‘visible‘ }); modalBG.fadeIn(this.options.animationspeed / 2); modal.delay(this.options.animationspeed / 2).animate({ "top": $(document).scrollTop() + topMeasure, "opacity": 1 }, this.options.animationspeed, this.unlockModal()); } if (this.options.animation == "fade") { modal.css({ ‘opacity‘: 0, ‘visibility‘: ‘visible‘, ‘top‘: $(document).scrollTop() + topMeasure }); modalBG.fadeIn(this.options.animationspeed / 2, function () { $(this).css(‘opacity‘, 0.6); }); modal.delay(this.options.animationspeed / 2).animate({ "opacity": 1 }, this.options.animationspeed, this.unlockModal()); } if (this.options.animation == "none") { modal.css({ ‘visibility‘: ‘visible‘, ‘top‘: $(document).scrollTop() + topMeasure }); modalBG.css({ "display": "block" }); this.unlockModal() } } }, closeModal: function (CModal) { if (!locked) { CModal.lockModal(); if (CModal.options.animation == "fadeAndPop") { modalBG.delay(CModal.options.animationspeed).fadeOut(CModal.options.animationspeed); modal.animate({ "top": $(document).scrollTop() - topOffset, "opacity": 0 }, CModal.options.animationspeed / 2, function () { modal.css({ ‘top‘: topMeasure, ‘opacity‘: 1, ‘visibility‘: ‘hidden‘ }); CModal.unlockModal(); }); } if (CModal.options.animation == "fade") { modalBG.delay(CModal.options.animationspeed).fadeOut(CModal.options.animationspeed); modal.animate({ "opacity": 0 }, CModal.options.animationspeed, function () { modal.css({ ‘opacity‘: 1, ‘visibility‘: ‘hidden‘, ‘top‘: topMeasure }); CModal.unlockModal(); }); } if (this.options.animation == "none") { modal.css({ ‘visibility‘: ‘hidden‘, ‘top‘: topMeasure }); modalBG.css({ ‘display‘: ‘none‘ }); } } }, unlockModal: function () { locked = false; }, lockModal: function () { locked = true; }, show: function ($obj, CModal) { this.defaults = { animation: ‘fade‘, //fade, fadeAndPop, none animationspeed: 300, //how fast animtions are animationopacity: 0.6, // BG opacity closeonbackgroundclick: true, //if you click background will modal close? dismissmodalclass: ‘close-reveal-modal‘ //the class of a button or element that will close an open modal }; this.options = $.extend({}, this.defaults, this.options); /*--------------------------- Global Variables ----------------------------*/ modal = $obj, topMeasure = parseInt(modal.css(‘top‘)), topOffset = modal.height() + topMeasure, locked = false, modalBG = $(‘.reveal-modal-bg‘); /*--------------------------- Create Modal BG ----------------------------*/ if (modalBG.length == 0) { modalBG = $(‘<div class="reveal-modal-bg" />‘).insertAfter(modal); } /*--------------------------- Open and add Closing Listeners ----------------------------*/ //Open Modal Immediately this.openModal(); //Close Modal Listeners var closeButton = $(‘.‘ + this.options.dismissmodalclass).bind(‘click.modalEvent‘, function () { CModal.closeModal(CModal); }); if (this.options.closeonbackgroundclick) { modalBG.css({ "cursor": "pointer" }); modalBG.bind(‘click.modalEvent‘, function () { CModal.closeModal(CModal) }); } /*--------------------------- Open & Close Animations ----------------------------*/ //Entrance Animations //Closing Animation /*--------------------------- Animations Locks ----------------------------*/ }});
调用就很简单了:
m_CustomerModal = new CustomerModal(); m_CustomerModal.show($("#watingmodal"),m_CustomerModal);
这个是一个div框而已了,代码如下:
<div id="watingmodal" class="wating_modal spopup"> 请等待......</div>
关闭的时候如此调用:
m_CustomerModal.closeModal(m_CustomerModal);
虽然看起来有那么些别扭,但是Javascript的this关键字是比较特殊的,如果用call其实也是可以的,条条大路通罗马。
当然,别忘了样式:
.spopup{ top:200px;}.big-link { display:block; margin-top:100px; text-align:center; font-size:16px;}.reveal-modal-bg { position:fixed; height:100%; width:100%; background:#000; z-index:100; display:none; top:0; left:0; zoom:1; filter:alpha(opacity=70); opacity:0.7;}.reveal-modal { visibility:hidden; position: absolute; left:50%; margin-left:-300px; background:#EDEDED; z-index:101; border:#ACAEB4 solid 1px; border-radius:5px; behavior:url(js/PIE.htc);}.reveal-modal .close-reveal-modal { position:absolute; top:6px; right:12px; color:#aaa; cursor:pointer;} .reveal-modal .popuptitle{ height:28px; background:url(../images/dot03.gif) 12px 7px no-repeat; padding-left:35px;}.reveal-modal .popuptitle span{ position:relative; top:6px; line-height:20px; color:#E70000; letter-spacing:1px; font-weight:bold;}.reveal-modal .popupcontent{ background:#FFF; border:#C0C0C0 solid 1px; margin:0 4px 3px 4px;}.reveal-modal .popupcontent .popupbut{ width:100%; height:40px; border-top:#C0C0C0 solid 1px; background:#F4F4F4; text-align:right;}.reveal-modal .popupcontent .popupbut h1{ margin:9px 20px 0 0;}.reveal-modal .popupcontent .popupbut h1 input{ margin-left:4px;}.popupbutton{ height:22px; background:url(../images/graybutbg.png) repeat-x; border:#ABADB3 solid 1px; line-height:22px; text-align:center; padding:0 10px; cursor:pointer; color:#333;}.popupbutton_on{ height:22px; line-height:22px; text-align:center; padding:0 10px; cursor:pointer;}.wating_modal { visibility:hidden; position: absolute; left:50%; top:300px; margin-left:-200px; z-index:101; color:#FFF; font-weight:bold; font-size:14px; letter-spacing:1px;}
好吧。。我是不是专业美工,但是扣代码大家都会的吧,模版都给你了的说。。。改造完毕。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。