События JS: подключение события изменения значения на текстовые входы

У меня есть текстовый ввод, содержимое которого изменено script не пользователем. Поэтому я хотел бы запустить событие, когда значение изменится. Я не могу найти подходящее событие для этого. Я даже нашел qaru.site/info/20093/..., но это не то решение, которое я ищу.

Как сделать эту работу с jQuery и текстовым вводом, где значение установлено следующим образом:

myTextControl.value = someValue

Здесь я хочу запустить событие, чтобы увидеть новое значение.

Ответ 1

Я не могу найти подходящее событие для этого.

Да, нет никого.

Есть DOM Mutation Events, но они не поддерживаются хорошо в кросс-браузере и не загораются для значений формы, так или иначе не отражаются в атрибутах (кроме IE из-за ошибки).

Только в Mozilla для свойства скриптов можно установить JavaScript watch. Только в IE обработчик JScript onpropertychange может быть настроен так, чтобы улавливать как сценарированные, так и пользовательские изменения. В других браузерах вам придется использовать свой собственный опросчик интервалов для поиска изменений.

function watchProperty(obj, name, handler) {
    if ('watch' in obj) {
        obj.watch(name, handler);
    } else if ('onpropertychange' in obj) {
        name= name.toLowerCase();
        obj.onpropertychange= function() {
            if (window.event.propertyName.toLowerCase()===name)
                handler.call(obj);
        };
    } else {
        var o= obj[name];
        setInterval(function() {
            var n= obj[name];
            if (o!==n) {
                o= n;
                handler.call(obj);
            }
        }, 200);
    }
}

watchProperty(document.getElementById('myinput'), 'value', function() {
    alert('changed!');
});

Это очень неудовлетворительно. Он не будет реагировать на пользовательские изменения в Mozilla, он позволяет использовать только одно наблюдаемое свойство для каждого объекта в IE, а в других браузерах функция обработчика будет вызвана гораздо позже в потоке выполнения.

Почти наверняка лучше переписать части script, которые устанавливают value вместо вызова функции оболочки setValue, чтобы вы могли отслеживать изменения, которые вы хотите уловить.

Ответ 2

Вы можете добавить обычного слушателя событий в поле ввода, как это. (используя jQuery)

$(myTextControl).change(function() {
    ...
    /* do appropriate event handling here */
    ...
});

Хорошо, учитывая, что javascript, который изменяет входное значение, не контролируется вами, становится затруднительным. Осталось два варианта:

1.) Crossbrowser compatible: выполните опрос входного значения с помощью функции, которая непрерывно проверяет, изменилось ли значение. (Что-то в этом роде).

//at beginning before other scripts changes the value create a global variable
var oldValue = myTextControl.value;

function checkIfValueChanged() {
    if(myTextControl.value != oldValue) {
        $(myTextControl).trigger("change");
        clearInterval(checker);
    }
}

//every 500ms check if value changed
var checker = setInterval('checkIfValueChanged()', 500);

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

Если значение может несколько раз изменяться внешним script, просто запустите функцию интервала вместо ее отмены и просто обновите oldValue;

2.) AFAIK Пока не поддерживается всеми браузерами ( "проверьте его на тех, которые вам нужно поддерживать" )

Вы можете привязать к специальному DOM Level 3Event: DOMAttrModified (в Firefox, может быть, другие тоже я думаю, что у Opera есть это тоже, Safari??, Chrome??), и в IE, конечно, у него другое имя propertychange (и является проприетарным и отличается от поведения W3C)

В идеале вы могли бы объединить два параметра и проверить, существует ли поддержка для DOMAttrModified или propertychange, и соответственно использовать или отбрасывать на запрос опроса.


Чтение ссылок

События W3C DOM Mutation

W3C DOMAttrModified Event

MSDN DHTML propertychange Event

обновлен плагин мониторинга свойств jQuery CSS

Последняя ссылка - это какой-то парень, который в основном уже сделал плагин jQuery, выполнив описанные мной вещи (непроверенные мной, предоставленные как ссылка)

Ответ 3

попробуйте это

$('#myTextControl').bind('input', function(){
  console.log('value changed');
});

Ответ 4

var oldVal = $('#myTextControl').val();

//Your script that changes the value

if(oldVal != $('#myTextControl').val())
{
//Your content has changed, do something
}

Ответ 5

Вам нужно будет слушать события клавиатуры, когда элемент, который вы смотрите, имеет фокус.