首页 > 解决方案 > 用 onclick-event 替换搜索字段中的输入不会更新列表

问题描述

我有一个过滤三个不同列表的搜索字段。我想要一个onclick将文本添加到搜索字段并替换可能存在的任何其他值的事件。

我可以这样做,但onclick不会更新列表,除非我单击搜索字段并手动按 Enter。添加click()事件没有帮助。

同时,X在搜索字段中点击清除输入也不会更新列表。

我能做些什么?

<p onclick="document.getElementById('searchCombo').value = 'element 1'; document.getElementById('searchCombo').click()">Filter for: vitamins</p>

<p onclick="document.getElementById('searchCombo').value = 'element 2'; document.getElementById('searchCombo').click()">Filter for: drugs</p>

<p onclick="document.getElementById('searchCombo').value = 'element 3'; document.getElementById('searchCombo').click()">Filter for: medications</p>

<input type="search" id="searchCombo" placeholder="Search for combination...">

<ul ID="list1" class="combo">
    <li><a href="#">List 1 element 1</a></li>
    <li><a href="#">List 1 element 2</a></li>
    <li><a href="#">List 1 element 3</a></li>
    <li class="none">Nothing found in this category</li>
</ul>

<ul ID="list2" class="combo">
    <li><a href="#">List 2 element 1</a></li>
    <li><a href="#">List 2 element 2</a></li>
    <li><a href="#">List 2 element 3</a></li>
    <li class="none">Nothing found in this category</li>
</ul>

<ul ID="list3" class="combo">
    <li><a href="#">List 3 element 1</a></li>
    <li><a href="#">List 3 element 2</a></li>
    <li><a href="#">List 3 element 3</a></li>
    <li class="none">Nothing found in this category</li>
</ul>

这是javascript:

<script>
    /* drug combo search */
    const select_all = (selector, selectee = document) =>
        Array.from(selectee.querySelectorAll(selector));

    const hide_item = item => item.style.display = 'none';
    const show_item = item => item.style.display = '';
    const item_text = item => item.textContent.toLowerCase();
    const compare = text => item => item_text(item).includes(text);
    const has_class = class_name => item => item.className.includes(class_name);
    const not_has_class = class_name => item => !has_class(class_name)(item);

    const filter_list = text => list => {
        let lis = select_all("li", list);
        let to_show = lis
            .filter(not_has_class('none'))
            .filter(compare(text));

        if (to_show.length === 0)
            to_show = lis.filter(has_class('none'));

        lis.forEach(hide_item);
        to_show.forEach(show_item);
    };

    const filter = (event) =>
        select_all(".combo").forEach(
            filter_list((event?.target?.value || '').toLowerCase())
        );

    document.getElementById('searchCombo').addEventListener("keyup", filter);

    filter();

</script>

标签: javascripthtml

解决方案


如果您对 HTML 有一定的灵活性,我的建议是:

如果您不想要它们,我认为您不需要 a 标签,只要您将它们移到class="filter_to" data-filter_to_term="element 1"p 标签。

const select_all = (selector, selectee = document) =>
  Array.from(selectee.querySelectorAll(selector));

const hide_item = item => item.style.display = 'none';
const show_item = item => item.style.display = '';
const item_text = item => item.textContent.toLowerCase();
const compare = text => item => item_text(item).includes(text);
const has_class = class_name => item => item.className.includes(class_name);
const not_has_class = class_name => item => !has_class(class_name)(item);

const filter_list = text => list => {
  let lis = select_all("li", list);
  let to_show = lis
    .filter(not_has_class('none'))
    .filter(compare(text));

  if (to_show.length === 0)
    to_show = lis.filter(has_class('none'));

  lis.forEach(hide_item);
  to_show.forEach(show_item);
};

const search_box = document.getElementById('searchCombo');

const filter = (text) =>
  select_all(".combo").forEach(
    filter_list((text || '').toLowerCase())
  );

const set_filter = (text) => {
  search_box.value = text;
  filter(text);
};

const onclick_filter_to = (event) => {
  event.preventDefault();
  set_filter(event.target.dataset.filter_to_term);
};

select_all(".filter_to").forEach(
  (element) => element.addEventListener("click", onclick_filter_to)
);

search_box.addEventListener("input", event => filter(event.target.value));

filter();
<p><a href="#" class="filter_to" data-filter_to_term="element 1">Filter for: vitamins</a></p>

<p><a href="#" class="filter_to" data-filter_to_term="element 2">Filter for: drugs</a></p>

<p><a href="#" class="filter_to" data-filter_to_term="element 3">Filter for: medications</a></p>

<input type="search" id="searchCombo" placeholder="Search for combination...">

<ul ID="list1" class="combo">
    <li><a href="#">List 1 element 1</a></li>
    <li><a href="#">List 1 element 2</a></li>
    <li><a href="#">List 1 element 3</a></li>
    <li class="none">Nothing found in this category</li>
</ul>

<ul ID="list2" class="combo">
    <li><a href="#">List 2 element 1</a></li>
    <li><a href="#">List 2 element 2</a></li>
    <li><a href="#">List 2 element 3</a></li>
    <li class="none">Nothing found in this category</li>
</ul>

<ul ID="list3" class="combo">
    <li><a href="#">List 3 element 1</a></li>
    <li><a href="#">List 3 element 2</a></li>
    <li><a href="#">List 3 element 3</a></li>
    <li class="none">Nothing found in this category</li>
</ul>

看起来用输入替换 keyup 可能适用于 Chrome 中的取消 X 按钮(但我以前没有使用过)。


推荐阅读