【问题标题】:How do I programmatically force an onchange event on an input?如何以编程方式强制输入上的 onchange 事件?
【发布时间】:2010-09-13 06:59:15
【问题描述】:

如何以编程方式强制输入上的 onchange 事件?

我尝试过这样的事情:

var code = ele.getAttribute('onchange');
eval(code);

但我的最终目标是触发任何侦听器函数,但这似乎不起作用。更新“值”属性也不行。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    如果你使用 jQuery,你会:

    $('#elementId').change(function() { alert('Do Stuff'); });
    

    或 MS AJAX:

    $addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });
    

    或者在元素的原始 HTML 中:

    <input type="text" onchange="alert('Do Stuff');" id="myElement" />
    

    在重新阅读问题后,我想我错过了阅读要做什么。我从来没有找到以强制更改事件的方式更新 DOM 元素的方法,您最好做的是拥有一个单独的事件处理程序方法,如下所示:

    $addHandler($get('elementId'), 'change', elementChanged);
    function elementChanged(){
      alert('Do Stuff!');
    }
    function editElement(){
      var el = $get('elementId');
      el.value = 'something new';
      elementChanged();
    }
    

    由于您已经在编写一个 JavaScript 方法来进行更改,因此只需额外调用 1 行代码。

    或者,如果您正在使用 Microsoft AJAX 框架,则可以通过以下方式访问所有事件处理程序:

    $get('elementId')._events
    

    它允许你做一些反射式的工作来找到正确的事件处理程序来触发。

    【讨论】:

    • 我相信他想触发实际事件,而不是在触发事件时运行函数......我认为。大声笑
    【解决方案2】:

    呃,不要对任何东西使用 eval。嗯,有些东西,但它们非常罕见。 相反,你会这样做:

    document.getElementById("test").onchange()
    

    在此处查看更多选项: http://jehiah.cz/archive/firing-javascript-events-properly

    【讨论】:

    • 评估 JSON ;)
    • json2.js 用于对象化 JSON! JSON.parse 已经在现代浏览器上可用
    • 此技术在通过设置“onchange”附加更改处理程序时有效。它不会生成触发 w3c 或 microsoft 事件处理程序的“真实”事件。有关详细信息,请参阅链接。
    • 我认为这个答案现在已经过时了,Miscreant's answer 使用 new Event(...)dispatchEvent 似乎是当今正确的解决方案。
    • 此答案已过时;如果您使用Element.addEventListener 处理事件,上面的代码将不起作用。要以现代方式实现它,请参阅@Miscreant 的回答。
    【解决方案3】:

    取自QUnit底部

    function triggerEvent( elem, type, event ) {
        if ( $.browser.mozilla || $.browser.opera ) {
            event = document.createEvent("MouseEvents");
            event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
                0, 0, 0, 0, 0, false, false, false, false, 0, null);
            elem.dispatchEvent( event );
        } else if ( $.browser.msie ) {
            elem.fireEvent("on"+type);
        }
    }
    

    当然,您可以将 $.browser 替换为您自己的浏览器检测方法,使其独立于 jQuery。

    要使用这个功能:

    var event;
    triggerEvent(ele, "change", event);
    

    这基本上会触发真正的 DOM 事件,就好像某些事情已经真正改变了一样。

    【讨论】:

      【解决方案4】:

      由于某种原因 ele.onchange() 在我的页面上的 IE 中为我抛出“找不到方法”异常,所以我最终使用了来自链接 Kolten 提供的这个函数并调用 fireEvent(ele, 'change '),这很有效:

      function fireEvent(element,event){
          if (document.createEventObject){
              // dispatch for IE
              var evt = document.createEventObject();
              return element.fireEvent('on'+event,evt)
          }
          else{
              // dispatch for firefox + others
              var evt = document.createEvent("HTMLEvents");
              evt.initEvent(event, true, true ); // event type,bubbling,cancelable
              return !element.dispatchEvent(evt);
          }
      }
      

      然而,我确实创建了一个测试页面,确认调用应该 onchange() 工作:

      <input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
      <input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>
      

      编辑:ele.onchange() 不起作用的原因是因为我实际上没有为 onchange 事件声明任何内容。但 fireEvent 仍然有效。

      【讨论】:

      • 我比我提供的示例更喜欢这种浏览器检测方法(通过对象检测)。
      • 这对 Firefox 23 不再有效:“element.dispatchEvent 不是函数”
      • 谷歌同事们好。现在是 2016 年!如今,我们编写类似element.dispatchEvent(new Event('change', true, true)) 的代码,而不是那些晦涩难懂且大多已弃用的createEventinitEvent 代码。
      【解决方案5】:

      在 jQuery 中我主要使用:

      $("#element").trigger("change");
      

      【讨论】:

      • 这对我有帮助!我正在使用代码设置复选框的值(选中与否),无论我做什么,事件都没有在 IE 中触发。我尝试了 blur() focus() 和其他一些东西。在我设置了我调用触发器的值之后,我也添加了一个点击事件来调用触发器。它会引起多起火灾,但对我来说并不重要。在 IE 中,我通过代码添加复选框,您必须在更改事件触发之前单击它们两次。感谢您的提示。
      • 作为更新,$("#element").change();从 jquery 1.0 开始做同样的事情。
      • 请注意,这不会触发原生 onchange。它只会在所有通过 jQuery 绑定的 onchange 监听器上触发!
      【解决方案6】:

      使用 JQuery,您可以执行以下操作:

      // for the element which uses ID
      $("#id").trigger("change");
      
      // for the element which uses class name
      $(".class_name").trigger("change");
      

      【讨论】:

      • undefined 不是函数。
      【解决方案7】:

      创建一个Event 对象并将其传递给元素的dispatchEvent 方法:

      var element = document.getElementById('just_an_example');
      var event = new Event('change');
      element.dispatchEvent(event);
      

      这将触发事件侦听器,无论它们是通过调用addEventListener 方法还是通过设置元素的onchange 属性来注册的。


      如果您希望事件冒泡,您需要将第二个参数传递给Event 构造函数:

      var event = new Event('change', { bubbles: true });
      

      关于浏览器兼容性的信息:

      【讨论】:

      • 是的,MDN Creating and triggering events 是一个很好的资源!
      • 这就是如何正确地做到这一点,本机。现在所有浏览器都支持:caniuse.com/#feat=dispatchevent
      • 这是这个问题的正确答案。我们必须以现代方式实现这一目标。
      • 我试图在 IE11 上做同样的事情,但在尝试更改 reactjs 输入字段时它不起作用。 var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
      • 为什么大家都说这是最好的答案?根据链接的事件文档,即使是当前版本的 IE still 也不支持这一点。
      【解决方案8】:

      这是IE和Chrome最正确的答案::

      var element = document.getElementById('xxxx');
      var evt = document.createEvent('HTMLEvents');
      evt.initEvent('change', false, true);
      element.dispatchEvent(evt);
      

      【讨论】:

        【解决方案9】:

        用于触发 Javascript 中的任何事件。

         document.getElementById("yourid").addEventListener("change", function({
            //your code here
        })
        

        【讨论】:

        • 这是监听事件,而不是触发它们。
        【解决方案10】:

        如果您使用这段代码添加所有事件:

        //put this somewhere in your JavaScript:
        HTMLElement.prototype.addEvent = function(event, callback){
          if(!this.events)this.events = {};
          if(!this.events[event]){
            this.events[event] = [];
            var element = this;
            this['on'+event] = function(e){
              var events = element.events[event];
              for(var i=0;i<events.length;i++){
                events[i](e||event);
              }
            }
          }
          this.events[event].push(callback);
        }
        //use like this:
        element.addEvent('change', function(e){...});
        

        那么您可以只使用element.on&lt;EVENTNAME&gt;(),其中&lt;EVENTNAME&gt; 是您的事件名称,这将使用&lt;EVENTNAME&gt; 调用所有事件

        【讨论】:

          猜你喜欢
          • 2022-11-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-26
          • 2011-01-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多