【问题标题】:onchange event not fire when the change come from another function当更改来自另一个函数时,onchange 事件不会触发
【发布时间】:2011-10-26 17:03:46
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: javascript dom-events


    【解决方案1】:

    来自fine manual

    改变
    当控件失去输入焦点并且其值在获得焦点后已被修改时,会发生更改事件。此事件对 INPUT、SELECT 和 TEXTAREA 有效。元素。

    当您通过代码修改文本输入的值时,不会触发更改事件,因为没有焦点更改。您可以使用createEventdispatchEvent 自己触发事件,例如:

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

    还有一个现场版:http://jsfiddle.net/ambiguous/nH8CH/

    【讨论】:

    • 如果您使用任何现代事件监听方法,这将不起作用;仅当您使用旧的 onchange 属性时,它才会起作用。您应该使用 DOM 事件 API 来触发事件。
    • @Delan:你能说我很久没写原生 JavaScript 了吗?我会补上的。
    【解决方案2】:

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

    var e = document.createEvent('HTMLEvents');
    e.initEvent('change', false, false);
    some_input_element.dispatchEvent(e);
    

    【讨论】:

    • 必须是HTMLEvents吗? jQuery 版本显然使用了Event,我能看到的唯一区别是 DOM 级别 2 与级别 3。
    • 据我所知,HTMLEventsEventEvents 是同义词。
    • Event 似乎是官方的,Events 可能在某些浏览器中出现以匹配hasFeature 的复数形式。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      一个更可重用的选项:

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

      【讨论】:

        【解决方案5】:

        只需在 getter 和 setter 中使用 getAttribute("value")setAttribute("value", newValue) 重新定义节点的“value”属性,并在 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)
        &lt;input id="myNode"&gt;

        【讨论】:

          【解决方案6】:

          您可以使用keypress 事件来代替change

          这是因为 change 事件在不再聚焦之前不会触发 - 当您点击输入标签时。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-08-22
            • 1970-01-01
            • 1970-01-01
            • 2012-06-12
            • 1970-01-01
            • 2013-02-08
            • 1970-01-01
            相关资源
            最近更新 更多