jquery封装下拉框搜索过滤,点击下拉框外的区域下拉收起

82 阅读2分钟

利用Jquery封装下拉选择框,用class封装

1、创建class类:

 class SiteSelect {
    constructor(configParams) {
        this.boxId = configParams.boxId
        this.list = configParams.list
        this.showField = configParams.showField
        this.idField = configParams.idField
        this.childListField = configParams.childListField
        this.labelField = configParams.labelField
        this.placeholder = configParams.placeholder || '请选择'
        this.borderRadius = configParams.borderRadius || '25px'
        this.width = configParams.width || '100%'
        this.height = configParams.height || '50px'
        this.borderColor = configParams.borderColor || '#f2f3f5'
        this.callBack = configParams.cb
        this.createDOM()
        this.bindEvents()
        this.queryLiEvent()
    }
    
    createDOM() {
        var boxId = "'" + this.boxId + "'"
        var listDoms =
          '<span class="select-label" style="line-height:' +
          this.height +
          '">' +
          this.labelField +
          '</span>' +
          '<div class="select-list" style="width: ' +
          this.width +
          '; height: ' +
          this.height +
          '; border-color: ' +
          this.borderColor +
          '; position: relative;">' +
          '<div class="select-down-up select-up" style="width: ' +
          this.height +
          '; height: ' +
          this.height +
          ';" onclick="SiteSelect.downUpEvent(event, ' +
          boxId +
          ')"></div>' +
          '<input type="text" style="border-radius:' +
          this.borderRadius +
          '" oninput="SiteSelect.filterList(event,' +
          boxId +
          ')" onfocus="SiteSelect.focusInput(event, ' +
          boxId +
          ')" class="select_list_filter" placeholder="' +
          this.placeholder +
          '" />' +
          '<ul class="select-list-box" style="width: ' +
          this.width +
          '">' +
          this.liDoms(this.list) +
          '</ul>' +
          '</div>'

        $('#' + this.boxId).append(listDoms)
    }

      // 递归创建下拉框的dom节点
      liDoms(list) {
        var self = this
        var liDomsList = ''
        function renderItem(item, prefix) {
          var itemId = item[self.idField]
          var itemName = item[self.showField]
          if (!itemId || !itemName) {
            return
          }
          liDomsList += '<li class="select-list-item" id="' + itemId + '" title="' + itemName + '">' + prefix + '' + itemName + '</li>'
          if (item.hasChild && Array.isArray(item[self.childListField])) {
            item[self.childListField].forEach(function (child) {
              return renderItem(child, prefix + '--')
            })
          }
        }
        list.forEach(function (item) {
          return renderItem(item, '--')
        })
        return liDomsList
      }

      // 给下拉框绑定点击事件
      queryLiEvent() {
        var that = this
        var targetDom = $('#' + that.boxId).find('.select-list-box')[0]
        targetDom.addEventListener('click', function (e) {
          if (e.target == targetDom && targetDom.contains(e.target)) return
          var itemName = e.target.title
          var itemid = e.target.id
          $('#' + that.boxId)
            .find('.select_list_filter')
            .val(itemName)
          $('#' + that.boxId).find('.select-list-box')[0].style.height = '0px'
          $('#' + that.boxId)
            .find('.select-down-up')[0]
            .classList.remove('select-down')
          $('#' + that.boxId)
            .find('.select-down-up')[0]
            .classList.add('select-up')
          that.callBack && that.callBack(e, itemid)
        })
      }

      // 点击下拉框以外的区域,下拉框关闭
      bindEvents() {
        var self = this
        document.addEventListener('click', function (e) {
          var dropdown = $('#' + self.boxId).find('.select-list-box')[0]
          var dropdown1 = $('#' + self.boxId)[0]
          var selectDom = $('#' + self.boxId).find('.select-down-up')[0]
          if (e.target !== dropdown && !dropdown.contains(e.target) && e.target !== dropdown1 && !dropdown1.contains(e.target)) {
            dropdown.style.height = '0px'
            selectDom.classList.remove('select-down')
            selectDom.classList.add('select-up')
          }
        })
      }

      // 下拉框展示收起的事件
      static downUpEvent(e, boxId) {
        var selectBtnDom = $('#' + boxId).find('.select-list-box')[0]
        if (e.target.classList.value.indexOf('select-up') > -1) {
          e.target.classList.remove('select-up')
          e.target.classList.add('select-down')
          selectBtnDom.style.height = '400px'
        } else if (e.target.classList.value.indexOf('select-down') > -1) {
          e.target.classList.remove('select-down')
          e.target.classList.add('select-up')
          selectBtnDom.style.height = '0px'
        }
      }

      // input框获取焦点的事件
      static focusInput(e, boxId) {
        var selectDownDom = $('#' + boxId).find('.select-down-up')[0]
        if (selectDownDom.classList.value.indexOf('select-up') > -1) {
          selectDownDom.classList.remove('select-up')
          selectDownDom.classList.add('select-down')
          $('#' + boxId).find('.select-list-box')[0].style.height = '400px'
        }
      }

      // 防抖函数
      debounceEve(func, delay) {
        var timeoutId
        return function () {
          var context = this
          var args = arguments
          clearTimeout(timeoutId)
          timeoutId = setTimeout(function () {
            func.apply(context, args)
          }, delay)
        }
      }

      // 过滤下拉列表--只是隐藏显示控制,不改变数据
      filterMethod(e, boxId) {
        var inputVal = e.target.value
        var listItems = $(`#${boxId}`).find('.select-list-item')
        listItems.each(function (_, item) {
          var isVisible = inputVal ? item.innerText.includes(inputVal) : true
          $(item).toggle(isVisible)
        })
      }

      static filterList(e, boxId) {
        var debouncedAction = this.prototype.debounceEve(this.prototype.filterMethod, 500)
        debouncedAction(e, boxId)
      }
}

2、使用

 <div id="college_box" style="margin-top: 50px; width: 400px; display: inline-block"></div>
 <script>
  var data = [
    {
      id: '1',
      name: '计算机科学与技术',
      hasChild: true,
      childCollegeList: [
        {
          id: '1-1',
          name: '软件工程',
          hasChild: true,
          childCollegeList: [
            {
              id: '1-1-1',
              name: '软件工程',
              hasChild: false,
              childCollegeList: [],
            },
            {
              id: '1-2-1',
              name: '计算机科学与技术',
              hasChild: false,
              childCollegeList: [],
            },
          ],
        },
        {
          id: '1-2',
          name: '计算机科学与技术',
          hasChild: false,
          childCollegeList: [],
        },
      ],
    }
  ]

  function test(e, id) {
    console.log(e, id)
  }
  var collageConfig = {
    boxId: 'college_box', // 容器id
    list: data, // 数据源
    showField: 'name', // 显示字段
    idField: 'id', // id字段
    childListField: 'childCollegeList', // 子列表字段
    labelField: '学院选择:', // label字段
    cb: test, // 点击选项的回调
    placeholder: '请选择学院', // placeholder字段
    borderRadius: '20px', // 边框圆角
    width: '300px', // 宽度
    height: '40px', // 高度
    borderColor: '#f2f3f5', // 边框颜色
  }

  var college = new SiteSelect(collageConfig)
 </script>

3、一些属性和字段都是可以配置的,想创建几个只需 new SiteSelect()实例,配置对应的属性即可;