Событие onchange не срабатывает, когда изменение происходит из другой функции

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

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

К сожалению, похоже, что это не вызывает событие, когда изменение происходит из функции javascript.

Как я могу заставить событие изменения работать, даже если изменение исходит от Javascript, а не от пользователя?


person baaroz    schedule 14.08.2011    source источник


Ответы (6)


Из отличного руководства:

change
Событие изменения происходит, когда элемент управления теряет фокус ввода, а его значение было изменено с момента получения фокуса. Это событие допустимо для INPUT, SELECT и TEXTAREA. элемент.

Когда вы изменяете значение ввода текста с помощью кода, событие изменения не будет запущено, потому что нет изменения фокуса. Вы можете инициировать событие самостоятельно с помощью createEvent и dispatchEvent, например:

el = document.getElementById('x');
ev = document.createEvent('Event');
ev.initEvent('change', true, false);
el.dispatchEvent(ev);

И живая версия: http://jsfiddle.net/ambiguous/nH8CH/

person mu is too short    schedule 14.08.2011
comment
Это не сработает, если вы используете какой-либо современный метод прослушивания событий; это будет работать, только если вы используете старое свойство onchange. Вы должны использовать API событий DOM для запуска событий. - person Delan Azabani; 14.08.2011
comment
@Delan: Можете ли вы сказать, что я давно не делал необработанный JavaScript? Я исправлю это. - person mu is too short; 14.08.2011

В функции, которая изменяет значение, вручную запустите событие change.

var e = document.createEvent('HTMLEvents');
e.initEvent('change', false, false);
some_input_element.dispatchEvent(e);
person Delan Azabani    schedule 14.08.2011
comment
Это должно быть HTMLEvents? Версия jQuery, по-видимому, использует Event, и единственная разница, которую я вижу, это уровень 2 DOM по сравнению с уровнем 3. - person mu is too short; 14.08.2011
comment
Насколько я знаю, HTMLEvents, Event и Events являются синонимами. - person Delan Azabani; 14.08.2011
comment
Event кажется официальным, Events вероятно, есть в некоторых браузерах, чтобы соответствовать множественному числу hasFeature. - person mu is too short; 14.08.2011

Сейчас 2018 год, и кажется, что функция initEvent() устарела: https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent

Я думаю, теперь вы можете инициировать событие в однострочном режиме: element.dispatchEvent(new Event('change'));

person Carl Chang    schedule 06.08.2018

Более многоразовый вариант:

function simulate_event(eventName, element) {
    // You could set this into the prototype as a method.
    var event;

    if (document.createEvent) {
        event = document.createEvent("HTMLEvents");
        event.initEvent(eventName, true, true);
    } else {
        event = document.createEventObject();
        event.eventType = eventName;
    };

    event.eventName = eventName;

    if (document.createEvent) {
        element.dispatchEvent(event);
    } else {
        element.fireEvent("on" + event.eventName, event);
    }
};
person Chris    schedule 07.10.2013

Просто переопределите свойство «value» узла, используя getAttribute("value") и setAttribute("value", newValue), в геттерах и сеттерах, а также отправьте событие «change» в конце сеттера. Например:

myNode.onchange = e => console.log("Changed!", e.target.value);

Object.defineProperty(myNode, "value", {
  get: () => myNode.getAttribute("value"),
  set(newValue) {
    myNode.setAttribute("value", newValue);
    myNode.dispatchEvent(new Event("change")); //or define the event earlier, not sure how much of a performance difference it makes though
  }
})

var i = 0;
setTimeout(function changeIt() {
    if(i++ < 10) {
        myNode.value = i;
        setTimeout(changeIt, 1000);
    }
}, 1)
<input id="myNode">

person bluejayke    schedule 07.08.2019

Вместо использования change вы можете использовать событие keypress.

Это связано с тем, что событие change не должно срабатывать до тех пор, пока оно больше не будет сфокусировано - когда вы щелкаете тег ввода.

person Alalade Samuel    schedule 11.06.2021