Javascript - JQuery on()clearTimeout范围问题

时间:2012-04-03 21:08:24

标签: javascript jquery settimeout

我进行了搜索和搜索,我对这一个人说空了。救命!我正在使用JQuery on()观察键盘事件的输入字段(#filter_query)。当用户将一些文本打入此输入字段时,on()会触发setTimeout(),然后该触发器会触发该站点的搜索功能。我试图避免搜索被触发,如果用户继续键入输入字段,因此clearTimeout()。由于某种原因,不会为clearTimeout保留超时ID,并且每次都会生成一个新ID。

这是我的代码:

$(document).on('keyup', '#filter_query', function (event) {
    var iTimeoutID,
        iTypingDelay = 800,
        sFilterVal = $.trim($('#filter_query').val()),
        sFilterCat = $('#filter_catagory').val(),
        sFilterCol = $('#filter_col').val();

    clearTimeout(iTimeoutID);

    if (sFilterVal !== "") {
        iTimeoutID = setTimeout(
                    function () {
                        searchFunction();
                    },
                    iTypingDelay
                    );
    }
});

使用上面的代码,无论clearTimeout()如何,我的搜索功能都会被多次触发。谢谢!

2 个答案:

答案 0 :(得分:0)

因为您正在定义变量var iTimeoutID,这意味着它不是全局变量,只能在该函数内部访问。因此,当再次调用该函数时,它会创建一个新变量。

我相信你应该能够通过不声明变量var iTimeoutID来解决它。

我可能错了所以如果有的话,请有人纠正我。

答案 1 :(得分:0)

您的iTimeoutID.on()事件处理函数的局部变量,因此每次该函数完成时都会销毁它,并在下次重新创建时被销毁。将它从该范围移到更高级别或全局级别,以便它可以从一个事件存活到下一个事件。

你可以这样做;

var iTimeoutID = null;
$(document).on('keyup', '#filter_query', function (event) {
    var iTypingDelay = 800,
        sFilterVal = $.trim($('#filter_query').val()),
        sFilterCat = $('#filter_catagory').val(),
        sFilterCol = $('#filter_col').val();

    if (iTimeoutID) {
        clearTimeout(iTimeoutID);
        iTimeoutID = null;
    }

    if (sFilterVal !== "") {
        iTimeoutID = setTimeout(function() {
            iTimeoutID = null;
            searchFunction();
        }, iTypingDelay);
    }
});

如果你想避免使用全局变量,或者你有多个这样的变量,你可以使用jQuery的.data()在这个对象上存储定时器id:

$(document).on('keyup', '#filter_query', function (event) {
    var self = $(this);
    var iTimeoutID = self.data("timerID") || null;
    var iTypingDelay = 800,
        sFilterVal = $.trim($('#filter_query').val()),
        sFilterCat = $('#filter_catagory').val(),
        sFilterCol = $('#filter_col').val();

    if (iTimeoutID) {
        clearTimeout(iTimeoutID);
        iTimeoutID = null;
    }

    if (sFilterVal !== "") {
        iTimeoutID = setTimeout(function() {
            self.data("timerID", null);
            searchFunction();
        }, iTypingDelay);
    }
    self.data("timerID", iTimeoutID);
});

这是另一个版本,它使用一个自执行函数作为一些变量的shell,这些变量可以遍历事件处理程序而不是全局:

(function() () {
    var iTimeoutID = null;
    $(document).on('keyup', '#filter_query', function (event) {
        var iTypingDelay = 800,
            sFilterVal = $.trim($('#filter_query').val()),
            sFilterCat = $('#filter_catagory').val(),
            sFilterCol = $('#filter_col').val();

        if (iTimeoutID) {
            clearTimeout(iTimeoutID);
            iTimeoutID = null;
        }

        if (sFilterVal !== "") {
            iTimeoutID = setTimeout(function() {
                iTimeoutID = null;
                searchFunction();
            }, iTypingDelay);
        }
    });
})();

如果这是快速的,并且几乎没有机会与其他代码发生冲突,并且事件处理程序只提供了一个对象,那么第一个选项就完全可以了。

如果.on()事件处理程序提供了多个对象,并且每个对象都需要跟踪它自己的状态,那么第二个选项就是完美的。

如果在同一个事件处理程序中没有多个对象,那么第三个选项是阻止添加任何新的全局变量的最简单方法。