当更改来自另一个函数时不会触发 onchange 事件

IT技术 javascript dom-events
2021-03-15 12:47:53

我有一个输入文本,它从一个 Javascript 函数(一个带倒计时的计时器)中获取他的值。

我想在输入文本为 0 时引发一个事件,所以我正在使用更改 eventListener。

不幸的是,当更改来自 javascript 函数时,它似乎没有引发事件。

即使更改来自 Javascript 而不是来自用户,我如何强制更改事件起作用?

6个回答

精美的手册

change
当控件失去输入焦点并且其值在获得焦点后已被修改时,将发生 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/

@Delan:你能说我有很长时间没有使用原始 JavaScript 了吗?我会补上的
2021-04-20 12:47:53
如果您使用任何现代事件侦听方法,这将不起作用;仅当您使用旧onchange属性时它才会起作用您应该使用 DOM 事件 API 来触发事件。
2021-04-24 12:47:53

在更改值的函数中,手动触发change事件。

var e = document.createEvent('HTMLEvents');
e.initEvent('change', false, false);
some_input_element.dispatchEvent(e);
据我所知HTMLEventsEventEvents是同义词。
2021-04-25 12:47:53
Event好像是官方的,Events大概是在一些浏览器中左右匹配hasFeature复数。
2021-04-27 12:47:53
有必要HTMLEvents吗?jQuery 版本显然使用Event,我能看到的唯一区别是 DOM 级别 2 与级别 3。
2021-05-02 12:47:53

现在是 2018 年,似乎 initEvent() 已弃用:https : //developer.mozilla.org/en-US/docs/Web/API/Event/initEvent

我认为您现在可以在单行中触发事件: element.dispatchEvent(new Event('change'));

一个更可重用的选项:

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);
    }
};

只需在 getter 和 setter 中使用getAttribute("value")and重新定义节点的“value”属性,setAttribute("value", newValue)在 setter 的末尾分派“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">