亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

基于jQuery的下拉菜單插件,諸位上眼?。?!

標簽:
JQuery

前言


很久没有写博客了,话说真的工作后才发现很多需要学的,有很多不足。

加之最近工作没有什么沉淀,现在团队又面临解散,反正闲着也是闲着,就自己写了个插件,反正水平就这样,当时自我总结吧!

应用背景


在我们工作中,经常会遇到这种需求:

① 鼠标点击某个文本框时出现下拉菜单

② 常用的操作鼠标划上出现下拉菜单

③ 按钮类应用

我们会用到这种功能往往原因是因为地方小了,按钮多了,这往往说明产品设计一般出问题了。。。 但是,我辈屁民豪不关注产品(没资格插手),所以需要完成以上功能;

其实总的来说,这些功能还是非常实用的。

于是,为了应对以上场景,我工作中先是做了一个,然后又遇到了,然后又遇到了,所以最后就写了这么一个东西。

集中展示


几个功能放到一起了,前端代码如下:

View Code

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4     <title></title> 5     <style type="text/css"> 6 body{ font: 12px/1.231 tahoma,arial,宋体; } 7 .drop_list_items , .drop_list_items ul { display: none; position:absolute; background-color: #FFFFFF; border: 1px solid #D2D2D2; padding: 2px; margin: 0; } 8 .drop_list_items li { margin: 0; padding: 4px; list-style: none; cursor: pointer; } 9 .drop_list_items li:hover { background-color: #3399FF; }10 .drop_list_items li.parent_drop_list { padding: 4px; list-style: none; }11 .drop_list_items li.cur_active { background-color: #3399FF; }12 .z800 { z-index: 800; }     13     </style>14     <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="http://www.cnblogs.com/jquery-1.7.1.min.js"></script>15     <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="DropList.js" type="text/javascript"></script>16     <script type="text/javascript">17 18         //方案一19         $(document).ready(function () {20             new DropList({21                 id: 'click_btn_drop',22                 dropItems: [23                                 ['短信选定用户', 'select'],24                                 ['短信全部用户', 'all'],25                                 ['短信未发送用户用户', 'all_else']26                             ],27                 func: function (e, scope, listEl) {28                     var el = $(this);29                     alert(el.html());30                     scope.closeList();31                     var s = '';32                 }33             });34 35             new DropList({36                 id: 'div1',37                 open: '1',38                 close: '1',39                 dropItems: [40                     ['昵称'],41                     ['姓名'],42                     ['性别'],43                     ['联系方式']44                 ],45                 func: function (e, scope, listEl, toggleEl) {46                     var el = $(this);47                     scope.closeList();48                     toggleEl.val(el.html());49                 }50             });51 52             new DropList({53                 id: 'click_text_drop',54                 dropItems: [55                     ['昵称'],56                     ['姓名'],57                     ['性别'],58                     ['联系方式']59                 ],60                 func: function (e, scope, listEl, toggleEl) {61                     var el = $(this);62                     scope.closeList();63                     toggleEl.val(el.html());64                 }65             });66 67         });68     </script>69 </head>70 <body>71 72 73 <div id="click_btn_drop"  style=" width:140px;" >74 点击按钮出现下拉菜单75 </div>76 <br />77 <br />78  79 80 <input id="click_text_drop"  type="text" />81 <br />82 <br />83   <div id="div1"  style=" width:140px;" >84 鼠标滑动85 </div>86 87 </body>88 </html>

 

js代码:

View Code

var DropList = function (opts) {    if (!opts.id) {        alert('请指定触发展开事件的元素id');        return false;    }    //触发展开元素id    this.toggleId = opts.id;    this.toggleEl = opts.id ? $('#' + opts.id) : $('body');    this.key = opts.id ? opts.id + '_list' : new Date().getTime();    this.open = opts.open || 'click'; //展开菜单方式 mousein    this.close = opts.close || 'click'; //关闭菜单方式 mouseleave    //this.initShow = false; //判断是否初始化出现菜单绑定事件    /*下拉菜单数据,可能出现多级菜单数据格式:    [['v', 'k', []], ['v', {}, []],     ['v', 'k', [['v', 'k', []], ['v', 'k', []]]    ]    */    this.dropItems = opts.dropItems || null;    this.loadData = opts.loadData; //用于异步加载下拉菜单数据//具有层级关系    this.listEl = null;    this.func = opts.func || null; //点击时的事件处理    //同步方式加载    if (this.dropItems) {        this.initDropItems();        this.eventBind();    } else {    }};DropList.prototype.closeList = {};DropList.prototype.dropItemLoad = function (data, el) {    for (var i in data) {        var item = data[i];        var tmp = $('<li></li>');        el.append(tmp); //标签已装载        if (item[0]) {            tmp.html(item[0]);        }        if (item[1] || typeof item[1] == 'number') {            if (typeof item[1] == 'string' || typeof item[1] == 'number') {                tmp.attr('id', item[1]);            } else {                for (_k in item[1]) {                    tmp.attr(_k, item[1][_k]);                }            }        }        if (item[2] && item[2]['length']) {//此处需要递归            var child = $('<ul ></ul>')            tmp.append(child);            tmp.addClass('parent_drop_list');            this.dropItemLoad(item[2], child);        }    }};//['v', 'k', []]DropList.prototype.initDropItems = function () {    var scope = this;    var dropItems = scope.dropItems;    var listEl = $('<ul class="drop_list_items" id="' + scope.key + '"></ul>');    $('body').append(listEl);    scope.dropItemLoad(dropItems, listEl);    scope.listEl = listEl;};DropList.prototype.closeList = function () {    var listEl = this.listEl;    listEl.find('li').removeClass('cur_active');    listEl.find('ul').hide();    listEl.hide();};DropList.prototype.eventBind = function () {    var scope = this;    var listEl = scope.listEl;    var toggleEl = scope.toggleEl;    var open = scope.open;    var close = scope.close;    var func = scope.func;    var obj_len = function (o) {        var len = 0;        for (var k in o) {            len++;        }        return len;    };    var func_cls = function () {        if (close == 'click') {            $(document).click(function (e) {                var el = $(e.target);                var is_el = false;                //判断父元素是否为                while (el.attr('id') != scope.key) {                    if (el.is("ul") || el.is('li')) {                        is_el = true;                        el = el.parent();                    } else {                        break;                    }                }                if (el.attr('id') == scope.toggleId) {                    is_el = true;                }                if (!is_el) {                    scope.closeList();                    if (scope.closeList[scope.toggleId])                        delete scope.closeList[scope.toggleId];                    if (obj_len(scope.closeList) == 0)                        $(document).unbind('click');                    var s = '';                }            });        } else {            listEl.mouseleave(function (e) {                scope.closeList();                if (scope.closeList[scope.toggleId])                    delete scope.closeList[scope.toggleId];                listEl.unbind('mouseleave');            });        }    };    //确认弹出层位置    var func_init_pos = function (el) {        var offset = el.offset();        var h = el.height();        var p_top = el.css('padding-top');        var p_bottom = el.css('padding-bottom');        listEl.css('min-width', (parseInt(el.css('width')) + parseInt(el.css('padding-left')) + parseInt(el.css('padding-right')) - 6) + 'px')        listEl.css('left', parseInt(offset.left) + 'px');        listEl.css('top', (parseInt(offset.top) + parseInt(h) + parseInt(p_top) + parseInt(p_bottom)) + 'px');    };    if (open == 'click') {        toggleEl.unbind('click').click(function (e) {            var el = $(this);            var drop_list_items = $('.drop_list_items');            func_init_pos(el);            drop_list_items.removeClass('z800');            listEl.addClass('z800');            listEl.show();            func_cls();            scope.closeList[scope.toggleId] = 1;            //e.stopPropagation(); //阻止冒泡        });    } else {        toggleEl.unbind('mouseenter').mouseenter(function (e) {            var el = $(this);            var drop_list_items = $('.drop_list_items');            func_init_pos(el);            drop_list_items.removeClass('z800');            listEl.addClass('z800');            listEl.show();            func_cls();            //e.stopPropagation(); //阻止冒泡        });    }    listEl.delegate('li', 'mouseenter', function (e) {        var el = $(this);        listEl.find('li').removeClass('cur_active');        listEl.find('ul').hide();        el.addClass('cur_active');        el.children().show();        el = el.parent();        while (el.attr('id') != scope.key) {            if (el.is("li")) {                el.addClass('cur_active');            }            if (el.is('ul')) {                el.show();            }            el = el.parent();        }        e.stopPropagation();    });    if (func && typeof func == 'function') {        listEl.delegate('li', 'click', function (e) {            func.call(this, e, scope, listEl, toggleEl);            e.stopPropagation();        });    }};function initNewDrop(opts) {    new DropList(opts);}

 

难点&后续


做的过程中还是遇到了几个问题的,比如:

① 菜单展开后如何关闭

② 多级菜单如何处理

不完善的级联效果

③ 事件如何回调

最后做出了这个比较简陋的东东。。。。

但是做完后也发现了一些问题:

① 像这种菜单在最左最下出现时没有解决;

② 然后菜单项过多时候也没有出现像select的滚动条;

③ 由于个人水平,整个代码的质量亦有问题;

④ 开始也考虑了异步数据加载的问题,但是着实有点难便放弃了,功能代码有一点,有兴趣的同学可以看看:

View Code

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  2 <html xmlns="http://www.w3.org/1999/xhtml">  3 <head>  4     <title></title>  5     <style type="text/css">  6         *  7         {  8           margin:0;     9         } 10         body 11         { 12             font: 12px/1.231 tahoma,arial,宋体; 13         } 14         div 15         { 16           width:160px; 17           margin:5px; 18         } 19     20         .drop_btn ul 21         { 22             position:absolute; 23             background-color: #FFFFFF; 24             border: 1px solid #D2D2D2; 25             padding: 2px; 26             line-height: 18px; 27             display: none; 28             top: 25px; 29             z-index: 500; 30              31         } 32          33         .drop_btn li 34         { 35             list-style: none; 36         } 37         .drop_btn_toggle 38         { 39             background: url("http://shz.qq.com/statics/images/button.png") repeat-x scroll 0 0 #E5E5E5; 40             border: 1px solid #999999; 41             box-shadow: 0 1px 0 #E5E5E5; 42             border-radius: 3px; 43             cursor: pointer; 44             height: 28px; 45             line-height: 28px; 46             *height: 18px; 47             *line-height: 18px; 48             padding: 3px 6px; 49             vertical-align: middle; 50             zoom:1; 51         } 52         .drop_btn_open .drop_btn_toggle 53         { 54             background: url("http://shz.qq.com/statics/images/button_selected.png") repeat-x scroll 0 0 #B4B4B4; 55             border-color: #CCCCCC #B1B1B1 #AFAFAF #BEBEBE; 56             color: #515151; 57         } 58         .drop_btn_toggle .icon 59         { 60             border-left: 4px dashed transparent; 61             border-right: 4px dashed transparent; 62             border-top: 4px solid; 63             display: inline-block; 64             width: 0; 65             height: 0; 66             margin: 11px 0 0 4px; 67             *margin: 6px 0 0 4px; 68             overflow: hidden; 69             vertical-align: top; 70         } 71          72         div.drop_btn_open ul 73         { 74             display: block; 75         } 76         .drop_btn li 77         { 78             padding: 2px; 79             cursor: pointer; 80         } 81         .drop_btn li:hover 82         { 83             background-color: #3399FF; 84         } 85     </style> 86     <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="http://www.cnblogs.com/jquery-1.7.1.min.js"></script> 87     <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="DropList.js" type="text/javascript"></script> 88     <script type="text/javascript"> 89  90         //方案一 91         $(document).ready(function () { 92             var click = new DropList({ 93                 id: 'click_btn_drop', 94                 toggleText: '给用户发送短信', 95                 openType: 'move', 96                 drop_items: [ 97                     { id: 'select', text: '短信选定用户' }, 98                     { id: 'all', text: '短信全部用户' }, 99                     { id: 'all_else', text: '短信未发送用户用户' }100                 ],101                 func: function (e, container) {102                     var el = $(this);103                     alert(el.html())104                     var s = '';105                 }106             });107 108             var move = new DropList({109                 id: 'move_btn_drop',110                 toggleText: '给用户发送短信',111               112                 loadData: function (callBack) {113                     var scope = this;114                     $.get('Handler.ashx', function (data) {115                         if (data && typeof data == 'string') {116                             data = eval('(' + data + ')');117                         }118                         data = data.data;119                         var param = [];120                         param.push({ text: '报名人数:' + data.reg_num });121                         var type = data.notice;122                         if (type == 0) {123                             msg = '不发送短信';124                         } else if (type == 1) {125                             msg = '自动短信';126                         } else if (type == 3) {127                             msg = '手动短信';128                         }129                         param.push({ text: '短信类型:' + msg });130                         param.push({ text: '<a href="#">自动短信条数:' + data.sms_auto_count + '</a>'});131                         param.push({ text: '<a , function (e) {402             func.call(this, e, container, toggleEl);403         });404     }405 };

 

 

所以先贴出来和各位看看,后续小生再行优化,希望能把这个功能做好!

 

 

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消