События Javascript: получение уведомлений об изменениях управляющего значения <input> - PullRequest
7 голосов
/ 29 сентября 2008

У меня следующая проблема:

У меня есть текстовое поле HTML (<input type="text">), содержимое которого изменено скриптом, к которому я не могу прикоснуться (это моя страница, но я использую внешние компоненты).

Я хочу получать уведомления в своем скрипте каждый раз, когда значение этого текстового поля изменяется, чтобы я мог реагировать на него.

Я пробовал это:

txtStartDate.observe('change', function() { alert('change' +  txtStartDate.value) });

который (как и ожидалось) не работает. Он выполняется только в том случае, если я сам изменяю значение текстового поля с помощью клавиатуры, а затем перемещаю фокус в другое место, но не выполняется, если сценарий изменяет значение.

Есть ли еще одно событие, которое я могу слушать, о котором я не знаю?



Я использую библиотеку Prototype, и, в случае необходимости, внешний компонент, изменяющий значение текстового поля, - Basic Date Picker (www.basicdatepicker.com)

Ответы [ 6 ]

5 голосов
/ 29 сентября 2008

Как вы и предполагали, изменения (и другие события) срабатывают только тогда, когда пользователь предпринимает какие-либо действия. Скрипт, модифицирующий вещи, не будет запускать какие-либо события. Ваше единственное решение состоит в том, чтобы найти какой-то крючок в элементе управления, который вы можете подключить к слушателю.

Вот как бы я это сделал:

basicDatePicker.selectDate = basicDatePicker.selectDate.wrap(function(orig,year,month,day,hide) {
  myListener(year,month,day);
  return orig(year,month,day,hide);
});

Это основано на беглом взгляде с Firebug (я не знаком с компонентом). Если есть другие способы выбора даты, вам нужно также обернуть эти методы.

4 голосов
/ 29 сентября 2008

addEventListener (" DOMControlValueChanged " будет срабатывать при изменении значения элемента управления, даже если оно выполняется сценарием.

addEventListener (" input " - отфильтрованная версия DOMControlValueChanged, инициированная пользователем).

К сожалению, DOMControlValueChanged в настоящее время поддерживается только Opera, и поддержка входных событий в webkit нарушена. Событие ввода также имеет различные ошибки в Firefox и Opera.

Этот материал, вероятно, скоро будет прояснен в HTML5, fwiw.

Обновление:

Начиная с 9.09.2012, поддержка DOMControlValueChanged была удалена из Opera (поскольку она была удалена из HTML5), а поддержка событий 'input' теперь намного лучше в браузерах (включая меньше ошибок).

2 голосов
/ 29 сентября 2008

IE имеет событие onpropertychange , которое можно использовать для этой цели.

Для настоящих веб-браузеров (;)) есть событие мутации DOMAttrModified , но за несколько минут экспериментов в Firefox я не смог заставить его запустить текст ввод, когда значение изменяется программно (или с помощью обычного ввода с клавиатуры), но оно срабатывает, если я изменяю имя входа программно. Любопытнее и любопытнее ...

Если вы не можете заставить это работать надежно, вы всегда можете просто регулярно опрашивать значение ввода:

var value = someInput.value;

setInterval(function()
{
    if (someInput.value != value)
    {
        alert("Changed from " + value + " to " + someInput.value);
        value = someInput.value;
    }
}, 250);
1 голос
/ 29 сентября 2008

В зависимости от того, как был написан внешний javascript, вы всегда можете переписать соответствующие части внешнего скрипта в вашем скрипте и перезаписать его во внешнем определении, чтобы вызвать событие изменения.

Раньше мне приходилось делать это со скриптами, которые были вне моего контроля.

Вам просто нужно найти внешнюю функцию, полностью скопировать ее как новую функцию с тем же именем и переписать скрипт, чтобы сделать то, что вы хотите.

Конечно, если скрипт был написан правильно с использованием замыканий, вы не сможете изменить его слишком легко ...

0 голосов
/ 29 сентября 2008

Мне пришлось один раз изменить элемент управления датируемой страницей YUI в соответствии с рекомендациями Дэна. Это грубая сила, но она сработала в решении моей проблемы. То есть найдите метод, пишущий в поле, скопируйте его код и добавьте оператор, запускающий событие изменения, а в своем коде просто обработайте это событие изменения. Вы просто должны переопределить исходную функцию с этой новой версией. Опрос, хотя он работает нормально, кажется мне гораздо более ресурсоемким решением.

0 голосов
/ 29 сентября 2008

Помимо решения проблемы, подобной тому, как объяснил Ной, вы также можете просто создать таймер, который проверяет значение каждые несколько сотен миллисекунд.

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