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

我打算构建一个自动完成搜索框,搜索 大约包含 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 并且如果进一步键入退格键,则它在给出结果时开始减慢。应该怎么做才能加快搜索速度?


森栏
浏览 318回答 1
1回答

HUX布斯

在每一个keydown你eventListener触发你的autocomplete功能。当有人点击backspace时,你会同时得到一堆keydown's,而现在,这意味着你同时运行了该函数多次。这就是减缓一切的原因。例如,如果我输入“Hello my name is”然后删除整个字符串,我会触发您的搜索 16 次,搜索 12,000 x 16 条记录!你可以开始明白为什么这会成为一个问题。debounce 函数很容易解决这个问题,因为它设置了再次运行之间的延迟。IE。如果有人刚刚擦除了整个字符串,它可能只触发一次。这是 debounce 函数的一个很好的例子:&nbsp; &nbsp; // http://davidwalsh.name/javascript-debounce-function&nbsp; &nbsp; function debounce(func, wait, immediate) {&nbsp; &nbsp; &nbsp; &nbsp; var timeout;&nbsp; &nbsp; &nbsp; &nbsp; return function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var context = this, args = arguments;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var later = function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timeout = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!immediate) { func.apply(context, args); }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var callNow = immediate && !timeout;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clearTimeout(timeout);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timeout = setTimeout(later, wait);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (callNow) { func.apply(context, args); }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }这就是你如何在你的代码上实现它以实现自动完成:searchElement.addEventListener("keydown", debounce(function(e) {&nbsp; &nbsp; &nbsp; &nbsp; var x = document.getElementById(this.id + "autocomplete-list");&nbsp; &nbsp; &nbsp; &nbsp; if (x) x = x.getElementsByTagName("div");&nbsp; &nbsp; &nbsp; &nbsp; if (e.keyCode == 40) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addActive(x);&nbsp; &nbsp; &nbsp; &nbsp; } else if (e.keyCode == 38) { //up&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addActive(x);&nbsp; &nbsp; &nbsp; &nbsp; } else if (e.keyCode == 13) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (init > -1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (x) x[init].click();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }}, 500)); // Time set here as callback for how often it should be run, change this to whatever you want the time delay to be.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript