首页 前端知识 原生js实现下拉框,支持多选、搜索

原生js实现下拉框,支持多选、搜索

2024-02-02 09:02:47 前端知识 前端哥 934 313 我要收藏

原生js实现下拉框,支持多选、搜索

就是一些事件绑定,话不多说上代码。

使用起来的话就调用init方法
1.搜索框与选中结果同框

<!--
 * @Description: 
 * @Autour: lkx
 * @Date: 2023-10-07 13:47:03
 * @LastEditors: lkx
 * @LastEditTime: 2023-12-21 20:17:25
-->
<!DOCTYPE html>
<html>

<head>
  <style>
    .custom-select {
      width: 260px;
      position: relative;
      display: flex;
      align-items: flex-start;
      border: 1px solid #999;
      border-radius: 5px;
    }

    .custom-select-content {
      width: 100%;
      min-height: 32px;
      max-height: 120px;
      overflow-x: hidden;
      overflow-y: auto;
    }

    .select-input {
      width: 254px;
      height: 26px;
      margin-right: 20px;
      border: none;
    }

    .select-input:focus {
      outline: none;
    }

    .select-result-label {
      display: block;
      height: 32px;
      line-height: 32px;
    }

    .select-list {
      position: absolute;
      left: 0;
      bottom: 0;
      transform: translateY(110%);
      width: 260px;
      min-height: 32px;
      max-height: 120px;
      overflow-x: hidden;
      overflow-y: auto;
      border: 1px solid #999;
      border-radius: 5px;
    }

    .select-list div {
      padding: 2px 4px;
      box-sizing: border-box;
    }

    .select-list div:hover {
      background-color: #eee;
      cursor: pointer;
    }

    .selected {
      color: blue;
    }

    .select-result {
      display: flex;
      flex-wrap: wrap;
      box-sizing: border-box;
    }

    .select-result div {
      height: 26px;
      border: 1px solid #999;
      border-radius: 5px;
      padding: 3px;
      margin: 3px;
      box-sizing: border-box;
      display: flex;
      align-items: center;
    }

    .select-result div span:last-of-type {
      display: inline-block;
      border: 1px solid #999;
      height: 8px;
      width: 8px;
      border-radius: 100%;
      padding: 2px;
      line-height: 7px;
      text-align: center;
      font-size: 12px;
      margin-left: 3px;
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div class="custom-select">
    <div class="custom-select-content">
      <div class="select-result select-box "></div>
      <input type="text" class="select-input" placeholder="搜索">
    </div>
    <div class=" select-list select-box " style=" display: none;"></div>
  </div>


  <script>
    const selectContent = document.querySelector('.custom-select .custom-select-content')
    const selectInput = document.querySelector('.custom-select .custom-select-content .select-input')
    const selectList = document.querySelector('.custom-select .select-list')
    const selectResult = document.querySelector('.custom-select .custom-select-content .select-result')

    let selectInputBlurTimes = null
    let selectDataHit = []
    let selectDataAll = []

    // 事件绑定
    selectInput.addEventListener('input', () => {
      const elList = Array.from(selectList.querySelectorAll('div'))
      selectList.style.display = (!selectInput.value || elList.findIndex(item => item.textContent.includes(selectInput.value)) !== -1) ? 'block' : 'none'
      Array.from(selectList.querySelectorAll('div')).forEach(item => {
        item.style.display = (!selectInput.value || item.textContent.includes(selectInput.value)) ? 'block' : 'none'
      })
    })
    document.addEventListener('click', e => {
      selectList.style.display = e.target.className.includes('select-input') || e.target.className.includes('select-list') || e.target.className.includes('select-result-close') || (e.target.offsetParent && e.target.offsetParent.className.includes('select-list')) ? 'block' : 'none'
    })
    selectContent.addEventListener('click', e => {
      selectInput.focus()
      selectList.style.display = 'block'
      selectInput.scrollIntoView({ behavior: 'smooth', block: 'center' })
      e.stopPropagation()
    })

    // 生成下拉列表
    const createSelectList = (content) => {
      const div = document.createElement('div')
      div.addEventListener('click', () => {
        if (selectDataHit.includes(content.value)) {
          selectDataHit.splice(selectDataHit.indexOf(content.value), 1)
          Array.from(selectResult.querySelectorAll('div span')).find(item => item.textContent === content.label).parentNode.remove()
          div.classList.remove('selected')
        } else {
          selectDataHit.push(content.value)
          createSelectResult(content)
          div.classList.add('selected')
        }
      })
      div.textContent = content.label
      selectList.append(div)
    }

    // 生成选中列表
    const createSelectResult = (content) => {
      const div = document.createElement('div')
      const span = document.createElement('span')
      span.textContent = "x"
      span.className = 'select-result-close'
      span.addEventListener('click', () => {
        selectDataHit.splice(selectDataHit.indexOf(content.value), 1)
        selectList.querySelectorAll('div')[selectDataAll.findIndex(item => item.value === content.value)].classList.remove('selected')
        div.remove()
      })

      div.innerHTML = `
				<span>${content.label}</span>
			`
      div.append(span)
      selectResult.append(div)
      selectInput.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }

    // 初始化
    const init = () => {
      selectDataAll = [{ label: '111111', value: 111111 }, { label: '222222', value: 222222 }, { label: '333333', value: 333333 }, { label: '444444', value: 444444 }, { label: '5555555', value: 5555555 }, { label: '666666', value: 1116111 }, { label: '1111711', value: 1111711 }, { label: '1111181', value: 1118111 }, { label: '1111191', value: 1911111 },]
      selectDataAll.forEach(item => {
        createSelectList(item)
      })
    }

    init()
  </script>
</body>

</html>

2.输入框与选中结果分离

<!--
 * @Description: 
 * @Autour: lkx
 * @Date: 2023-10-07 13:47:03
 * @LastEditors: lkx
 * @LastEditTime: 2023-10-07 14:30:17
-->
<!DOCTYPE html>
<html>

<head>
  <style>
    .custom-select {
      position: relative;
      display: flex;
      align-items: flex-start;
    }

    .select-input {
      width: 254px;
      height: 26px;
      margin-right: 20px;
    }

    .select-box {
      width: 260px;
      min-height: 32px;
      max-height: 120px;
      overflow-x: hidden;
      overflow-y: auto;
      border: 1px solid #999;
      border-radius: 5px;
    }

    .select-result-label {
      display: block;
      height: 32px;
      line-height: 32px;
    }

    .select-list {
      position: absolute;
      left: 0;
      top: 40px;

    }

    .select-list div {
      padding: 2px 4px;
      box-sizing: border-box;
    }

    .select-list div:hover {
      background-color: #eee;
      cursor: pointer;
    }

    .selected {
      color: blue;
    }

    .select-result {
      display: flex;
      flex-wrap: wrap;
      box-sizing: border-box;
    }

    .select-result div {
      height: 26px;
      border: 1px solid #999;
      border-radius: 5px;
      padding: 3px;
      margin: 3px;
      box-sizing: border-box;
      display: flex;
      align-items: center;
    }

    .select-result div span:last-of-type {
      display: inline-block;
      border: 1px solid #999;
      height: 8px;
      width: 8px;
      border-radius: 100%;
      padding: 2px;
      line-height: 7px;
      text-align: center;
      font-size: 12px;
      margin-left: 3px;
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div class="custom-select">
    <input type="text" class="select-input" placeholder="搜索">
    <div class="select-list select-box " style="display: none;"></div>
    <span class="select-result-label">选中结果:</span>
    <div class="select-result select-box "></div>
  </div>


  <script>
    const selectInput = document.querySelector('.custom-select .select-input')
    const selectList = document.querySelector('.custom-select .select-list')
    const selectResult = document.querySelector('.custom-select .select-result')

    let selectInputBlurTimes = null
    let selectDataHit = []
    let selectDataAll = []

    // 事件绑定
    selectInput.addEventListener('input', () => {
      const elList = Array.from(selectList.querySelectorAll('div'))
      selectList.style.display = (!selectInput.value || elList.findIndex(item => item.textContent.includes(selectInput.value)) !== -1) ? 'block' : 'none'
      Array.from(selectList.querySelectorAll('div')).forEach(item => {
        item.style.display = (!selectInput.value || item.textContent.includes(selectInput.value)) ? 'block' : 'none'
      })
    })
    document.addEventListener('click', e => {
      selectList.style.display = e.target.className.includes('select-input') || e.target.className.includes('select-list') || e.target.className.includes('select-result-close') || (e.target.offsetParent && e.target.offsetParent.className.includes('select-list')) ? 'block' : 'none'
    })

    // 生成下拉列表
    const createSelectList = (content) => {
      const div = document.createElement('div')
      div.addEventListener('click', () => {
        if (selectDataHit.includes(content.value)) {
          selectDataHit.splice(selectDataHit.indexOf(content.value), 1)
          Array.from(selectResult.querySelectorAll('div span')).find(item => item.textContent === content.label).parentNode.remove()
          div.classList.remove('selected')
        } else {
          selectDataHit.push(content.value)
          createSelectResult(content)
          div.classList.add('selected')
        }
      })
      div.textContent = content.label
      selectList.append(div)
    }

    // 生成选中列表
    const createSelectResult = (content) => {
      const div = document.createElement('div')
      const span = document.createElement('span')
      span.textContent = "x"
      span.className = 'select-result-close'
      span.addEventListener('click', () => {
        selectDataHit.splice(selectDataHit.indexOf(content.value), 1)
        selectList.querySelectorAll('div')[selectDataAll.findIndex(item => item.value === content.value)].classList.remove('selected')
        div.remove()
      })

      div.innerHTML = `
				<span>${content.label}</span>
			`
      div.append(span)
      selectResult.append(div)
    }

    // 初始化
    const init = () => {
      selectDataAll = [{ label: '111111', value: 111111 }, { label: '222222', value: 222222 }, { label: '333333', value: 333333 }, { label: '444444', value: 444444 }, { label: '5555555', value: 5555555 }, { label: '666666', value: 1116111 }, { label: '1111711', value: 1111711 }, { label: '1111181', value: 1118111 }, { label: '1111191', value: 1911111 },]
      selectDataAll.forEach(item => {
        createSelectList(item)
      })
    }

    init()
  </script>
</body>

</html>
转载请注明出处或者链接地址:https://www.qianduange.cn//article/1085.html
标签
评论
发布的文章

Ajax用法总结

2024-02-14 09:02:07

JQuery之jsTree树形插件

2024-02-14 09:02:01

Why React Doesn‘t Need jQuery?

2024-02-14 09:02:00

jQuery模板字符串

2024-02-14 09:02:58

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!