为了账号安全,请及时绑定邮箱和手机立即绑定

addEventListener 在同一输入上多次执行函数

addEventListener 在同一输入上多次执行函数

森栏 2022-10-13 19:35:29
我打算构建一个自动完成搜索框,搜索 大约包含 12,000 多个数据的建议数据。jquery 从搜索框中获取值,搜索数据数组并将建议值存储在数组中,该数组将进一步用于填充建议。<input type="text" id="Search_box" placeholder="Search Data">$('#Search_box').on('input', function () {    suggester(document.getElementById("Search_box"));});以下函数从搜索框中获取输入值并搜索包含 12,000 多条记录的 search_array,并给出包含这些字符的数据列表作为建议。function suggester(searchElement) {var init;searchElement.addEventListener("input", function(e) {        var x, y, i, val = this.value;        closeAllLists();        if (!val) { return false;}        init = -1;        var search_value = $('#Search_box').val();        suggest_data = [];        re = new RegExp("\\b\\w*" + search_value + "\\w*\\b", "ig");        for (i = 0; i < search_array.length; i++) {                if(search_array[i].match(re))                         suggest_data = suggest_data.concat(search_array[i].match(re));        }        x = document.createElement("DIV");        x.setAttribute("id", this.id + "autocomplete-list");        x.setAttribute("class", "autocomplete-items");        x.setAttribute("onClick", "this.setSelectionRange(0, this.value.length)");        this.parentNode.appendChild(x);        for (i = 0; i < suggest_data.length; i++) {                y = document.createElement("DIV");                val = truncate(suggest_data[i],30);                reg = new RegExp(search_value, "ig");                n = val.search(reg);                res = suggest_data[i].substr(n,search_value.length);                val = val.replace(res, '<span class="text_highlighter">'+res+'</span>');                y.innerHTML = val;                y.innerHTML += "<input type='hidden' value='" + suggest_data[i]  + "'>";        }});但是,当单击退格键时,这种方法会减慢速度。addEventListener 函数被触发多次,因此它在建议的函数内循环以给出结果。例如,如果输入 ASD 并且如果进一步键入退格键,则它在给出结果时开始减慢。应该怎么做才能加快搜索速度?
查看完整描述

1 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

在每一个keydowneventListener触发你的autocomplete功能。当有人点击backspace时,你会同时得到一堆keydown's,而现在,这意味着你同时运行了该函数多次。这就是减缓一切的原因。

例如,如果我输入“Hello my name is”然后删除整个字符串,我会触发您的搜索 16 次,搜索 12,000 x 16 条记录!你可以开始明白为什么这会成为一个问题。

debounce 函数很容易解决这个问题,因为它设置了再次运行之间的延迟。IE。如果有人刚刚擦除了整个字符串,它可能只触发一次。

这是 debounce 函数的一个很好的例子:

    // http://davidwalsh.name/javascript-debounce-function

    function debounce(func, wait, immediate) {

        var timeout;

        return function() {

            var context = this, args = arguments;

            var later = function() {

                timeout = null;

                if (!immediate) { func.apply(context, args); }

            };

            var callNow = immediate && !timeout;

            clearTimeout(timeout);

            timeout = setTimeout(later, wait);

            if (callNow) { func.apply(context, args); }

        };

    }

这就是你如何在你的代码上实现它以实现自动完成:


searchElement.addEventListener("keydown", debounce(function(e) {

        var x = document.getElementById(this.id + "autocomplete-list");

        if (x) x = x.getElementsByTagName("div");

        if (e.keyCode == 40) {

            init++;

            addActive(x);

        } else if (e.keyCode == 38) { //up

            init--;

            addActive(x);

        } else if (e.keyCode == 13) {

            e.preventDefault();

            if (init > -1) {

                if (x) x[init].click();

            }

        }

}, 500)); // Time set here as callback for how often it should be run, change this to whatever you want the time delay to be.


查看完整回答
反对 回复 2022-10-13
  • 1 回答
  • 0 关注
  • 267 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号