如果你只会JQuery的插件式开发, 那么你可以进来看看?_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 如果你只会JQuery的插件式开发, 那么你可以进来看看?

如果你只会JQuery的插件式开发, 那么你可以进来看看?

 2013/11/27 11:28:11  李 维  博客园  我要评论(0)
  • 摘要:对于JQuery的学习,已经有3年多的时间了,直到去年与我的组长一起做项目,看到他写的JS,确实特别漂亮,有时甚至还看不太懂,我才发现其实我不太会JQuery。所以我有时间就会去看看他写的JS代码,直到今天我都会很怀恋那段在清大的日子,是我人生思想道路上的一次艳遇。我到现在都一直喜欢去看一些牛人的js文章,譬如像(叶小钗,司徒正美,tom大叔)等人的文章都是很不错的。上面的话说多了,来看看我如何输写JS代码,模块化的思路整理,大概有下面的几种情况:第一种:教你如何在项目中编写一个可以通用的弹框
  • 标签:插件 开发 jQuery

对于JQuery的学习,已经有3年多的时间了,直到去年与我的组长一起做项目,看到他写的JS,确实特别漂亮,有时甚至还看不太懂,

我才发现其实我不太会JQuery。所以我有时间就会去看看他写的JS代码,直到今天我都会很怀恋那段在清大的日子,是我人生思想道路上的一次艳遇。

我到现在都一直喜欢去看一些牛人的js文章,譬如像 (叶小钗,司徒正美,tom大叔)等人的文章都是很不错的。

上面的话说多了,来看看我如何输写JS代码,模块化的思路整理,大概有下面的几种情况:

第一种:教你如何在项目中编写一个可以通用的弹框,废除掉 alert("shit")

class="code_img_closed" src="/Upload/Images/2013112711/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('234e176b-df2b-4ed8-8bdd-794649aa389d',event)" src="/Upload/Images/2013112711/2B1B950FA3DF188F.gif" alt="" />
var alertBox = function (option) {
    //扩展区域
    var options = {
        w: '',
        title: '提示:',
        msg: '',
        msgExt: '',
        MsgArr: [],
        yes_btn: "确定",
        no_btn: "取消",
        yesBool: true,
        noBool: true,
        ok_Fun: null,
        backgroundColor: '#DC0100',
        AutoFun: null //----自执行函数----
    }
    //---继承合并,形成组合的options参数----
    option = $.extend({}, options, option || {});
    //--随机生成一个ID--
    var obj_msgprint = "msgprint_" + parseInt(Math.random() * 1000);
    //--确定--
    option.yes_btn = option.yesBool ? 

     "<a id='a_activateYes' style= background-color:" + option.backgroundColor + " href='javascript:;'>" + option.yes_btn + '</a>' : "";
    //--取消--
    option.no_btn = option.noBool ? '<a id="a_activateNo" class="cancel" href="javascript:;">' + option.no_btn + '</a>' : "";
    if (option.noBool) {
        noBtn = "";
    }

    var allMsgArr = [];
    if (option.MsgArr.length > 0) {
        for (var item in option.MsgArr) {
            allMsgArr.push("<p class='big'>" + option.MsgArr[item] + "</p>");
        };
    }
    if (option.msg != '') {
        allMsgArr.push("<p class='big'>" + option.msg + "</p>");
    }
    if (option.msgExt != '') {
        allMsgArr.push("<p style='text-align:center;'>" + option.msgExt + "</p>");
    }

    var boxContentArr = ["<div id='" + obj_msgprint + "' class='albox' style='position:absolute;z-index:1002;display:block;width:" + option.w + "'>
                          <div class='headbox' style='background-color: " + option.backgroundColor + "'>", "<p>" + option.title + "</p>", "</div>
                          <div class='conbox' style='border-color: " + option.backgroundColor + "'><div class='txt'>" + allMsgArr.join('') + "</div>
                          <div class='btnbox'>", option.yes_btn, option.no_btn, "</div></div></div>"];

    $("body").append(boxContentArr.join(''));
    $("#a_activateNo,#a_closeActivate,#a_activateYes").click(function () {
        $("#" + obj_msgprint).hide();
        mask.hide();
        $("#" + obj_msgprint).remove();
        mask.remove();
        if (option.ok_Fun && (typeof (option.ok_Fun) === 'function') && $(this).is("#a_activateYes")) {
            option.ok_Fun.apply();
        }
    });
    //按下回车键
    $(document).keypress(function (e) {
        var ev = e || event;
        if (ev.keyCode == 13) {
            $("#a_activateYes").trigger("click");
        }
    });
    //***************创建遮罩效果*****************/
    var mask = $("<div id=\"maskOfDiv\"></div>"); //--Div遮罩----
    $("body").append(mask);
    var sh = document.documentElement.scrollHeight,
    ch = document.documentElement.clientHeight,
    height = sh > ch ? sh : ch;
    mask.css({
        "position": "absolute",
        "top": "0",
        "right": "0",
        "bottom": "0",
        "left": "0",
        "z-index": "1000",
        "background-color": "#000000",
        "display": "none",
        "height": height
    });
    mask.show().css("opacity", "0.3");
    $("#" + obj_msgprint).show();
    //***************创建遮罩效果******************/
    //-------居中提示类型---------
    var dom_obj = document.getElementById(obj_msgprint);
    dom_obj.style.top = ((document.documentElement.clientHeight - $("#" + obj_msgprint).height()) / 2) + "px";
    dom_obj.style.left = (document.documentElement.scrollLeft + (document.documentElement.clientWidth - $("#" + obj_msgprint).width()) / 2) + "px";
    //------自动执行函数--------
    if (option.AutoFun && (typeof (option.AutoFun) === 'function')) {
        option.AutoFun.apply();
    }
}
window.alertBox = alertBox;
View Code

调用插件:

<script type="text/javascript">
     alertBox({ msg: "干掉alert,你看行不行!", yes_btn: "alertBox"});
</script>

大家可以重点去学习,$.extend()

               //---继承合并,形成组合的options参数----

              option = $.extend({}, options, option || {});

截图效果:

              

==========================================================

第二种: 教你如何用js的 prototype 原型链模式,做一个通用的验证插件。

var FormValidateCommon = function (containerObj, tipContainerFlag) {
    this.valObj = containerObj; //验证对象
    this.tipContainerBool = tipContainerFlag || false; //插入的位置标示 {true:本身,false:最后一个td}
    this.validatorArr = {}; // 验证对象容器

    //********************************************
    //---------现有可提供的枚举验证类型-------//
    //********************************************
    this.regexEnum = {
        idCard: /^[1-9]([0-9]{14}|[0-9]{16})([0-9]|X)$/, //身份证
        num: /^\-?([1-9]\d*)$/,         //数字
        email: /^([0-9A-Za-z\-_\.]+)@([0-9a-z]+\.[a-z]{2,3}(\.[a-z]{2})?)$/, //邮箱
        phone: /^1[3|4|5|8]\d{9}$/, //电话
        chinese: /^[\u0391-\uFFE5]{2,6}$/, //2-6位中文
        password: /^[a-zA-Z0-9_]{6,18}$/, //6-16位密码验证
        passwordBase: /^[a-zA-Z0-9_]*$/
    }

};
//=============扩展的原型方法============
FormValidateCommon.prototype =
    {
        init: function () {
            var scope = this;
            $(scope.valObj).find('.Validate').each(function () { //循环验证
                var el = $(this);
                scope.initItem(el);
            })
        },
        initItem: function (el) {
            if (typeof el == 'string') el = $("#" + el);
            var scope = this; //FormValidateCommon的作用域
            var cfg = el.attr('data-val');

            //若是未开启验证便退出该项初始化
            if (cfg.check && cfg.check == false) {
                return false;
            }

            if (cfg && cfg.length > 0) {
                cfg = eval('(' + cfg + ')'); //转成对象

                var check = cfg.check || true,
                id = el.attr('id') || Math.random(100000),
                initMsg = cfg.initMsg || '请填入信息',
                sucMsg = cfg.sucMsg || '格式正确',
                errorMsg = cfg.errorMsg || '请注意格式',
                requred = cfg.requred || false;
                cfg.id = id;
                cfg.check = check;
                cfg.initMsg = initMsg;  //默认信息
                cfg.sucMsg = sucMsg;     //验证成功信息
                cfg.errorMsg = errorMsg; //验证错误信息
                cfg.requred = requred;
                var tips = $("<span class='xx_czmsg'><img src='/Upload/Images/2013112711/1C8E4D4B78B15446.gif'>" + initMsg + "</span>");

                if (scope.tipContainerBool) { //插入到最后一个td
                    $("#" + id).parent().parent().find("td:last").html(tips);
                }
                else {  //插入到元素之间
                    tips.insertAfter(el);
                }
                cfg.el = el;
                cfg.tipEl = tips;


                //该表单的验证
                cfg.validate = function () {
                    scope.funcValidate(cfg);
                };

                //文本框验证
                el.blur(function () {
                    scope.funcValidate(cfg);
                });

                //下拉框验证
                if ($("#" + id).is("select")) {
                    el.change(function () {
                        scope.funcValidate(cfg);
                    });
                }
                scope.validatorArr[id] = cfg; //生成相关验证对象
            }
        },
        funcValidate: function (cfg) {
            var id = cfg.id;
            var el = cfg.el;
            var check = cfg.check; //判断是否开启验证
            var _this = this;

            //取消事件不执行逻辑
            if (!this.validatorArr[id])
                return false;

            //若是没有开启验证便忽略
            if (!check) {
                alert("验证");
                this.validatorArr[id]['state'] = 'ignore';
                return false;
            }
            var type = cfg.type;
            var regexObj = cfg.regexObj; //用户扩张的验证
            var ajaxObj = cfg.ajaxObj;   //ajax扩张的验证
            var compareObj = cfg.compareObj; //对比验证
            var msg = '';
            var isPass = 1; //{0:初始化提示,1:成功,-1:错误,2:必填}

            //--【1】----首先验证非空-------------------------
            if (cfg.requred) {
                if (el.val() == '' || el.val() == '0' || el.val() == null) {
                    isPass = 2; //必须项
                    //msg=cfg.initMstg;
                } else {
                    msg = cfg.sucMsg;
                }
            }
            //--【2】-----type优先,预定于的正则验证---------
            if (isPass == 1 && el.val().length > 0 && typeof type == 'string') {
                var reg = this.regexEnum[type];

                if (reg.test(el.val())) {
                    msg = cfg.sucMsg;
                } else {
                    isPass = -1;
                    msg = cfg.errorMsg;
                }
            }
            //--【3】------自身扩展的正则验证---------------
            if (isPass == 1 && el.val().length > 0 && regexObj) {
                var reg = regexObj;

                if (reg.test(el.val())) {
                    msg = cfg.sucMsg;
                } else {
                    isPass = -1;
                    msg = cfg.errorMsg;
                }
            }
            //--【4】-------验证比较字符串--------------------------
            if (isPass == 1 && el.val().length > 0 && compareObj) {
                var compareArr = compareObj.split('|');
                if (compareArr.length == 3) {
                    var _type = compareArr[0]
                    var _id = compareArr[1];
                    var _flag = compareArr[2];
                    var _v = el.val();
                    var _cv = $('#' + _id).val();
                    if (_type == 'num') {
                        _v = parseInt(_v);
                        _cv = parseInt(_cv);
                    }

                    if (_flag == '=') {
                        if (_v == _cv) {
                            msg = cfg.sucMsg;
                        } else {
                            isPass = -1;
                            msg = '两次密码输入不一致';
                        }
                    }
                }
            }
            //--【5】------------ajax验证-----------------------------
            if (isPass == 1 && el.val().length > 0 && ajaxObj) {
                var ajaxArr = ajaxObj.split('|');
                if (ajaxArr.length >= 2) {
                    var url = ajaxArr[0];
                    var _param = {};
                    _param[ajaxArr[1]] = el.val(); //文本框参数
                    //--------------扩展参数---------------------------
                    for (var i = 2; i < ajaxArr.length; i++) {
                        var arrObjParam = ajaxArr[i].split('=');
                        _param[arrObjParam[0]] = arrObjParam[1];
                    }

                    $.post(url, _param, function (data) {
                        if (typeof data == 'string') {
                            fata = eval('(' + data + ')');
                        }
                        if (data.code) {
                            msg = data.msg || cfg.sucMsg;
                        } else {
                            isPass = -1;
                            msg = data.msg;
                        }
                        ShowResult(_this, isPass);
                    });
                    return false; //在此中断后操作
                }
            }

            ShowResult(_this, isPass);

            //----------显示消息----------------
            function ShowResult(scope, isPass) {
                if (msg == '') isPass = 2;
                switch (isPass) {
                    case 0: //默认

                        scope.validatorArr[id]['state'] = 'tip';
                        scope.validatorArr[id]['tipEl'].html('<img src=/Upload/Images/2013112711/1C8E4D4B78B15446.gif>' + cfg.initMsg);
                        break;
                    case 1: //成功
                        scope.validatorArr[id]['state'] = 'success';
                        scope.validatorArr[id]['tipEl'].html('<img src=http://static.eee114.com/new_parents/images/xx_right.gif>' + msg);
                        break;
                    case -1: //验证有误
                        scope.validatorArr[id]['state'] = 'error';
                        scope.validatorArr[id]['tipEl'].html('<img src=http://static.eee114.com/new_parents/images/xx_no.gif>' + msg);
                        break;
                    case 2: //必填验证有误
                        scope.validatorArr[id]['state'] = 'error';
                        scope.validatorArr[id]['tipEl'].html('<img src=/Upload/Images/2013112711/1C8E4D4B78B15446.gif>' + cfg.initMsg);
                        break;
                    default:
                        break;
                }
            }
        },
        validatorAll: function () {
            for (var k in this.validatorArr) {
                var v = this.validatorArr[k];
                v.validate();
            }
        },
        validatorState: function () {
            for (var k in this.validatorArr) {
                if (this.validatorArr[k].state == 'error') {
                    return false;
                }
            }
            return true;
        }
    }
View Code

调用插件:

<form class="familyClass">
<input type="text" class="Validate" name="Phone" id="Phone" value="@Model.Phone"
data-val="{type:'phone',initMsg:'请输入您的手机号!',sucMsg:'手机号码验证成功!',errorMsg:'请输入正确的手机号!'}"/>
<form> <script type="text/javascript"> var familyForm = new FormValidateCommon(".familyClass", false); familyForm.init(); familyForm.validatorAll(); </script>

上面的调用实现了很灵活的自动式标签绑定验证,但是只适合一种一个项目的通用样式的提示。

大家可以重点去学习,FormValidateCommon.prototype = {}

截图效果:

 

============================================

第三种:用js制作实现一个漂亮的下拉框插件:selectPlus

(function ($) {
    $.fn.selectPlus = function (option) {
        option = $.extend({ index: 0, defaultClick: true }, option);
        return this.each(function () {
            var _this = $(this);
            var newSelect = _this.find(".seleitem");
            var _itemClick = null;
            newSelect.live({
                click: function () {
                    _itemClick = $(this);
                    //没有数据,则无效
                    if ($(this).find("p>a").length <= 0) {
                        return;
                    } else {
                        //---------------------------
                        if ($(this).hasClass("click")) {
                            closeSelect(this);
                        } else {
                            $(this).addClass("click");
                            $(this).find("p>a").show("fast").css("style", "display:block");
                            $(this).find("p>a.current").hide();
                        }
                    }
                },
                mouseleave: function () {
                    closeSelect(this);
                }
            });

            //隐藏p,移除click样式
            function closeSelect(obj) {
                $(obj).find("p>a").hide("fast");
                $(obj).removeClass("click");
            }

            //给p下面的a添加点击事件
            $(".seleitem p>a").live("click", function (e) {
                var src = e.target;
                var thisLink = $(this);

                if (src.tagName == "A") {
                    var PObj = thisLink.parent();
                    var a_show = PObj.siblings("a");

                    PObj.siblings("a").text(src.innerHTML);
                    PObj.siblings("a").attr("value", thisLink.attr("value"));

                    thisLink.parents(".seleitem").removeClass("click");
                    thisLink.addClass("current").siblings().removeClass("current");


                    //----------------------
                    thisLink.parents(".seleitem").children("[data-name='data']").attr("value", src.innerHTML);
                    thisLink.parents(".seleitem").children("[data-value='data']").attr("value", thisLink.attr("value"));
                    closeSelect(".seleitem");
                  
                }
            });
            //--------自动触发一下----------------------
            (function () {
                if (option.defaultClick) {
                    _this.find(".seleitem p>a").eq(option.index).trigger("click");
                    _this.find(".seleitem p>a").eq(option.index).attr("style", "display:none");
                }
            }());
        });
    }
})(jQuery);
View Code

调用插件:

 <div class="order">  
<div style="width: 124px;" class="seleitem"> <input type="hidden" name="pay-name" data-name="data" value="已支付"> <input type="hidden" name="orderPayNum" data-value="data" value="1"> <i id="opOption"></i> <a id="orderPay" class="show" href="javascript:void(0);" value="1">已支付</a> <p style="width: 140px; height: 55px;"> <a value="" href="javascript:void(0)" style="display: none;" class="">全部</a> <a value="0" href="javascript:void(0)" style="display: none;">未支付</a> <a value="1" href="javascript:void(0)" style="display: none;" class="current">已支付</a> </p> </div>
</div>
<script type="text/javascript">
$(function () {
         //-------------插件调用-------------------------------          $(".order").selectPlus({ index: 0 });//--支付状态,{index:为选中第一个}
            });
   </script>

截图效果:

             

======================================================================

第四种: : selectPlus                               

对于上面的selectPlus我还有话要说,对于插件的思想,未必真的就很好,看了BootStrap的一些插件源代码,你会发现,它还结合了一种绑定式的思想。

对于上面提到的所有插件式写法,其实我们都可以用绑定式的思想去简化代码量。

在上面的代码中加上,加上如下代码:

(function ($) {
$.fn.selectPlus = function (option) {
//.........可以参考上面的selectPlus.......
}

//----------很简单的关键代码-------------------
$(window).on('load', function () {
        //取得元素上带data-tip="on"的元素
        $('[data-select="on"]').each(function () {
            $(this).selectPlus();
        })
    })
});

调用变成了这样:

 <div class="order" data-select="on">  
      //..............
  </div>

 

希望小伙伴们也都能领悟,吃饭了哦!

发表评论
用户名: 匿名