jQuery 三级联动下拉插件

1,459 阅读3分钟

在开发工作中,有时候需要我们自己去手动开发一个插件,刚好我遇到了这样的机会,也有时间去完成这个插件,所以就做了一个适合自己的项目的三级联动下拉插件。

下面我来介绍下开发的过程:

1、 首先,我们需要构思好自己需要的什么样子的东西,然后根据图纸,先定好样式和基本模型。

我自己设计的页面如下:

这里写图片描述

我们需要一个点击的按钮,模拟成select的样式,后面的所属分类是展示我们的结果的地方。 下面的三个框,模拟的是下拉样式,点击第一个有分类的选项,出现第二个下拉,依次类推,最多是三组。

好了,下面我就来设计这样的jquery插件吧。

2、引入jquery,创建方法

我在页面中使用的是外部链接,apps.bdimg.com/libs/jquery…
然后我们来创建一个js文件,命名为 select.js,并引入到页面中。

在 select.js 中,我们创建一个立即执行函数

(function($){})(jQuery)

我们在参数中引入jQuery这个变量,然后再内部参数中,使用 $ 符来替代jQuery这个变量。

然后我们在函数内部创建对象,并在jquery的原型上添加我们的方法。

(function($){
  var selecter = {
      init: function (options) {
        return (function () {    })()
      }
  };
  $.fn.createSelect = function (opt) {
    var options = $.extend({},opt);
    selecter.init(options);
  }
})(jQuery)

在这个过程中,主要使用的是 $.extend() 方法来将我们默认的对象和传入的新对象进行合并。

在这里, init() 方法来实现函数的初始化,并且引入我们的参数options

3、实现 selecter 对象的方法

这里先上代码吧

(function ($) {
    var selecter = {
      // 初始化 
      init: function (options) {
        return (function () {
          selecter.fillHtml();
          selecter.bindEvent(options);
        })()
      },
      // 操作dom
      fillHtml: function (model, options) {
        return (function () {
          var model_select = '<ul class="model-select">';
          if (!model) {
            return;
          }

          $.each(options, function (item, index) {
            if ('object' === typeof index) {
              model_select += '<li class="select-item "> <span class="select-text">' + item +
                '</span> <em class="arrow"></em></li>';
            } else {
              model_select += '<li class="select-item">' + item + '</li>';
            }
          })
          model_select += '</ul>';
          model.append(model_select);

        })()
      },

      //绑定事件
      bindEvent: function (options) {
          // 取消事件
          $(".btn-box").off('click');
          $(".model-selects").off('click', '.select-item');
          //绑定事件 
          $(".btn-box").on('click', function () {
            var model_select = $(this).parent().find('.model-selects .model-select');
            var model_selects = $(this).parent().find('.model-selects');
            if (!$(this).hasClass('active')) {
              $(this).addClass('active');
              if (model_select.length > 0) {
                $(this).parent().find('.model-selects .model-select').show();
              } else {
                selecter.fillHtml(model_selects, options);
              }
            } else {
              $(this).removeClass('active');
              $(this).parent().find('.model-selects .model-select').hide();
            }
          });
          // 分级
          $(".model-selects").on('click', '.select-item', function (e) {
            var text = $(this).find('.select-text').text();
            var self = $(this);
            var nextAll = $(this).parent().nextAll();
            var e = e || window.event;
            e.stopPropagation();
            if (nextAll) {
              nextAll.remove();
            }
            if (text) { //继续分级
              var prev = $(this).parent().prev('ul').find('.active').find('.select-text').text();
              var model_selects = $(this).parents('.select-content').find('.model-selects');
              $.each(options, function (item, index) {
                if (text === item) {
                  selecter.fillHtml(model_selects, options[text]);
                } else {
                  if ('object' == typeof index) {
                    $.each(index, function (item, index2) {
                      if (text === item) {
                        selecter.fillHtml(model_selects, index[text]);
                      }
                    })
                  }
                }
              });
            } else { // 结束关闭
              var parent = $(this).parent();
              var prevs = parent.prevAll();
              var result = '所属分类:';
              var text = $(this).text();
              if (prevs.length === 0) {
                result += text;
              }
              if (prevs.length > 0) {
                for (var i = prevs.length - 1; i > -1; i--) {
                  var active = prevs.eq(i).find('.active');
                  var select_text = active.find('.select-text').text();
                  if (select_text) {
                    result += select_text + ">";
                  }
                }
                result += text;
              }
              console.log(result);
              $(".results").html(result);
              $(".btn-box").removeClass('active');
              $(this).parents('.model-selects').empty();
            }
            self.addClass('active').siblings('li').removeClass('active');
          });

          // 点击空白处关闭下拉,并获取值 
          $('body').click(function (e) {
            var target = $(e.target);
            if (!target.is('.model-selects *') && !target.is('.btn-box')) {
              if ($('.model-selects').is(':visible')) {
                var active = $(".model-selects").find('.active');
                var result = '';
                if( active.length === 0) {
                  $(".btn-box").removeClass('active');
                  $('.model-selects').empty();
                  return;
                }
                if( active.length === 1) {
                  result = active.text();
                  $(".results").html("所属分类:"+result);
                  $(".btn-box").removeClass('active');
                  $('.model-selects').empty();
                  return;
                }
                for (var i = active.length - 1; i > -1; i--){
                  var text = active.eq(i).text();
                  result += text + ">"
                }
                result = result.substr(0, result.length-1);
                $(".results").html("所属分类:"+result);
                $(".btn-box").removeClass('active');
                $('.model-selects').empty();
              }
            }
          });
        })()
      }
    }
    // 给jquery添加方法
    $.fn.createSelect = function (opt) {
      var options = $.extend({  // 默认参数
          '电子类': {
            '电子产品': {
              '二极管': '二极管',
              '电阻': '电阻',
              '电容': '电容'
            },
            '电子材料': '电子材料'
          },
          '服务类': {
            '服务产品': {
              '产品1': '产品1',
              '产品2': '产品2',
              '产品3': '产品3'
            },
            '服务工具': '服务工具'
          },
          '工程类': '工程类'
        },
        opt
      )
      // 初始化
      selecter.init(options);
    }
  })(jQuery)

我这里使用的是两个方法,一个 fillHtml() 来操作dom,一个 bindEvent() 来处理事件。

因为测试需要,我定义了一个默认的参数对象,下面来看看实现的结果
这里写图片描述

基本来我们的原型设计是一样的,能完成我们的功能。在实际开发中,我们的函数参数可以是ajax获取的json对象,按照我们的格式来处理,传入,就可以实现我们的三级联动下拉了。是不是很棒。


如果觉得不错,给了赞吧^_^。同时如果有小伙伴觉得我的代码可以优化的,欢迎指出。