Почему мой плагин jQuery не работает на нескольких селекторах? - PullRequest
1 голос
/ 04 марта 2011

Я создал селектор jQuery с именем jquery.observe_field .Это имитирует Поле наблюдения прототипа .Мой плагин работает нормально с «одиночными» селекторами, как ID селектор :

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

Но, похоже, он не работает (я не получаю никаких ошибок, но оповещенияпросто никогда не показывается) когда используется множественный селектор :

$('#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 ]

3 голосов
/ 04 марта 2011

Проблема в этой строке

frequency = frequency * 1000;

Для первого элемента частота установлена ​​на 1 с.

Для второго элемента частота установлена ​​на 1000 с.

Для третьего ...

Вы хотите, чтобы частота была установлена ​​правильно один раз не для каждого элемента.Так что сделайте это вне функции .each.Конечно, когда интервал удаляется и добавляется обратно, он добавляется с интервалом в 1000 с, что полностью нарушает ваш код.Представьте, что вы делаете это для 20 предметов.

Исправлено .

1 голос
/ 04 марта 2011

Примечание: Я знаю, что это не правильный ответ сейчас, но оставлю его здесь для дальнейшего использования заинтересованными лицами. Пожалуйста, смотрите ответ Райноса для правильного решения.

Посмотрев на ваш код, если вы закомментируете строку с чистым интервалом, тогда она начинает работать для первого поля ... Я думаю, что когда у вас есть более одного setinterval, они не очень хорошо играют с другие. Вероятно, все это связано с замыканиями и ограничениями и тому подобным, но я часто теряюсь в этих областях, поэтому не могу дать вам точного решения. Надеемся, что это приведет вас на правильный путь, а если нет, то и другой пользователь даст вам более полный ответ. :)

Редактировать, чтобы добавить: Мне приходит в голову, что решение может состоять в том, чтобы сохранить ссылку на таймер на самом элементе. Нечто подобное $this.data('timer',ti) или подобное. Возможно, вам придется немного поиграть, но это должно гарантировать, что каждый таймер будет в целости и сохранности и сам по себе, и когда вы его извлекаете ($this.data('timer'), вы можете быть уверены, что нет шансов ошибиться. :)

0 голосов
/ 04 марта 2011

@ egarcia я говорю, что почему вы хотите соединить, когда это работает, написав отдельно.

AFAIK Вы не можете определить свою функцию заранее:

function eventHandler(event) {}

и назначить ееотдельно:

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

С помощью .bind вы можете как минимум связать один обработчик событий с несколькими событиями.

Справочный вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...