RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1422381
Accepted
Arteil
Arteil
Asked:2022-08-21 15:17:19 +0000 UTC2022-08-21 15:17:19 +0000 UTC 2022-08-21 15:17:19 +0000 UTC

在 <select> 中查找元素

  • 772

有一个列表搜索<select>可以隐藏所有与搜索中输入的内容不匹配的项目。但是有一个问题,当在一个大列表(4500 个元素)中搜索时,它会挂起几秒钟。您还可以搜索或优化哪些其他方式?

document.addEventListener("click", function(e) {
    let input = document.getElementById(dataTargetID + 'Input'); 
    let val = input.value.trim().toUpperCase();
    let searchItems = document.querySelectorAll('#'+dataTargetID + ' option');
    if (e.target.classList.contains('keyboard__key')) {
        if (val != '') {
            searchItems.forEach(function (elem){
                if (elem.innerText.toUpperCase().search(val) == -1) {
                    elem.classList.add('hidden')
                }
                else {
                    elem.classList.remove('hidden');
                }
            });
        }
        else {
            searchItems.forEach(function (elem){
                elem.classList.remove('hidden');
            });
        }
    }
})
javascript html
  • 2 2 个回答
  • 83 Views

2 个回答

  • Voted
  1. Best Answer
    EzioMercer
    2022-08-21T17:13:12Z2022-08-21T17:13:12Z

    我认为它会更快,因为:

    • input无需每次搜索searchItems
    • includes 快于search
    • for of 快于forEach
    • 没有额外的if else

    // Prepare options (Start)
    const select = document.querySelector('#select');
    const fragment = document.createDocumentFragment();
    
    for (let i = 0; i < 4500; ++i) {
      const option = document.createElement('option');
      option.innerHTML = i + 1;
      
      fragment.append(option);
    }
    
    select.append(fragment);
    
    // Prepare options (End)
    
    
    const input = document.querySelector('#input');
    const searchItems = document.querySelectorAll('#select option');
    
    input.addEventListener('input', function(e) {
      const target = e.target;
      const val = target.value.trim().toUpperCase();
    
      if (!target.classList.contains('keyboard__key')) return;
    
      for (const elem of searchItems) {
        const needShow = val !== '' && !elem.innerText.toUpperCase().includes(val);
    
        elem.classList.toggle('hidden', needShow);
      }
    })
    .hidden {
      display: none;
    }
    
    input {
      position: absolute;
    }
    
    select {
      position: absolute;
      top: 50px;
    }
    <input id="input" class="keyboard__key">
    <select id="select" size="20">
    </select>

    我想出了一个没有类的变体,但是通过fragment-s。根据我的检查和在线测试,这在 FF 和 Chrome 中运行得更快。

    如果我理解正确,它会更快,因为:

    • 搜索option-ov 直接在select
    • 删除元素然后一次插入所有必要的元素比分别为每个元素分配一个类更快(老实说,我不知道为什么会这样,如果有人解释原因,我将非常感激)

    // Prepare options (Start)
    const select = document.querySelector('#select');
    const fragment = document.createDocumentFragment();
    
    for (let i = 0; i < 4500; ++i) {
      const option = document.createElement('option');
      option.innerHTML = i + 1;
      
      fragment.append(option);
    }
    
    select.append(fragment);
    
    // Prepare options (End)
    
    
    const input = document.querySelector('#input');
    const searchItems = select.querySelectorAll('option');
    
    input.addEventListener('input', function(e) {
      const target = e.target;
      const val = target.value.trim().toUpperCase();
      const fragment = document.createDocumentFragment();
    
      if (!target.classList.contains('keyboard__key')) return;
      
      for (const elem of searchItems) {
        elem.remove();
        
        if (val === '' || elem.innerText.toUpperCase().includes(val)) {
          fragment.append(elem);
        }
      }
    
      select.append(fragment);
    })
    input {
      position: absolute;
    }
    
    select {
      position: absolute;
      top: 50px;
    }
    <input id="input" class="keyboard__key">
    <select id="select" size="20">
    </select>

    • 3
  2. De.Minov
    2022-08-21T17:35:34Z2022-08-21T17:35:34Z

    一站式解决方案,用于多个input“查询”输入和select搜索。

    JS:

    const input = document.querySelectorAll('.search-select');
    let cache;
    
    [...input].map(elem => {
      const select = document.querySelector('#'+elem.dataset.for);
      if(select) {
        elem.addEventListener('focus', e => cache = [...document.querySelector('#'+e.target.dataset.for).children);
        elem.addEventListener('input', e => {
          if(e.target.value.length > 0) {
            cache.forEach(el => el.style.display = el.innerText.trim().includes(e.target.value) ? '' : 'none')
          } else cache.forEach(el => el.style.display = '');
        });
      }
    })
    

    Potestiv 注意到它.forEach的工作速度更快,因此使用它。
    .includes()在文本中找到任何匹配项,可以将其替换为另一个,但会减慢搜索速度。

    对我而言,主要优点是当focuse inputa 保存 a 的内容select(基本上是 all option)时,它会在迭代之后。

    HTML:

    <input type="text" class="search-select" data-for="select">
    <select id="select">
      <!-- ... -->
    </select>
    

    with 的绑定input与andselect类似,JS 会查找.labelinputselectinput[data-for]

    代码如何在 4500 选项上工作的示例


    Ps 如何比较和什么。我拿了一个 4500 的数组option,它在上面的链接上,并通过了一些方法:

    .map()- ~28ms
    .forEach()- ~6ms
    for()- ~26ms
    while() i++- ~21ms
    while(len--)- ~19ms

    迭代动作是用 even 隐藏元素value。
    测试代码


    我试图用 做一个变体.filter(),但它并没有变得更好,相反,执行时间增加了。

    我的代码使用值匹配,它.innerText从 4500option秒返回value并且innerText等于序数,与值匹配 -1需要约 131 毫秒。
    建议同事将搜索替换为.innerText,我尝试了一些选项,结果如下:

    .innerText- ~131ms
    .value- ~20ms - ~
    .innerHTML26ms
    .textContent- ~25ms
    .dataset- ~23ms

    对于后四个,差异不是特别明显,但建议使用.value.

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5