zoukankan      html  css  js  c++  java
  • 改造一个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%; 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{ 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;}

    好吧。。我是不是专业美工,但是扣代码大家都会的吧,模版都给你了的说。。。改造完毕。

  • 相关阅读:
    委托
    队列和栈、泛型
    Java去除字符串中 除数字和逗号以外的符号
    SQL查询重复记录
    使用EasyExcel导出图片及异常处理
    Nacos开机自启
    Redis开机自启
    Nginx开机自启
    Java 向数组中添加元素
    Java:如何打印整个字符串数组?
  • 原文地址:https://www.cnblogs.com/HouZhiHouJueBlogs/p/3862883.html
Copyright © 2011-2022 走看看