为什么我的jQuery插件在多个选择器上失败?

时间:2011-03-04 09:20:57

标签: javascript jquery jquery-plugins

我创建了一个名为jquery.observe_field的jQuery选择器。它模仿Prototype's observe_field。我的插件适用于“单个”选择器,例如ID selector

$('#foo').observe_field(1, function() { alert(this.value); });

但是当使用multiple selector时,它似乎不起作用(我没有收到任何错误,但警报从未显示过):

$('#foo,#bar,#baz').observe_field(1, function() { alert(this.value); });

为什么?

编辑:我在jsFiddle中创建了一个示例(请注意,在JavaScript部分,初始化代码就在插件代码之后):http://jsfiddle.net/X2Bzk/

(function($) {
    jQuery.fn.observe_field = function(frequency, callback) {
        return this.each(function() {
            var $this = $(this);
            var prev = $this.val();

            var check = function() {
                var val = $this.val();
                if (prev != val) {
                    prev = val;
                    $this.map(callback); // invokes the callback on $this
                }
            };

            var reset = function() {
                if (ti) {
                    clearInterval(ti);
                    ti = setInterval(check, frequency);
                }
            };

            check();
            frequency = frequency * 1000; // translate to milliseconds
            var ti = setInterval(check, frequency); // invoke check periodically
            // reset counter after user interaction
            $this.bind('keyup mousemove', reset); //mousemove is for selects
        });
    };
})(jQuery);

3 个答案:

答案 0 :(得分:3)

问题在于这一行

frequency = frequency * 1000;

对于第一项,频率设置为1s。

对于第二项,频率设置为1000s。

对于第三个......

您想要为每个项目正确设置一次频率。所以在.each函数之外做。当然,当间隔被移除并添加回来时,它会以1000s的间隔重新添加,这会完全破坏你的代码。想象一下,为20件物品做这件事。

Fixed

答案 1 :(得分:1)

注意:我知道现在这不是正确的答案,但会留在这里供以后参考。请参阅Raynos的答案以获得正确的解决方案。

看了你的代码,如果你用清除间隔注释掉那一行,那么它就开始为第一个字段工作......我在想,如果你有一个以上的setinterval他们没有很好地与其他。它可能与封闭和范围等有关,但我常常迷失在这些区域,所以无法给你一个确切的解决方案。希望它能让你走上正确的道路,或者如果没有让另一个用户走上正确的道路,给你一个更完整的答案。 :)

编辑添加:我想到一个解决方案可能是将定时器引用存储在元素本身上。像$this.data('timer',ti)或类似的东西。您可能需要玩一下,但这应该确保每个计时器都保持安全和自己的声音,当您检索它($this.data('timer')时,您可以确定没有机会得到错误的计时器。 :)

答案 2 :(得分:-2)

@egarcia我说这就是为什么你想通过单独写作来组合起来。

AFAIK您无法预先定义您的功能:

function eventHandler(event) {}

并单独指定:

$('select').mouseover(eventHandler);
$('input').bind('keyup', eventHandler);

使用.bind,您至少可以将一个事件处理程序绑定到多个事件。

Reference Question