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


123

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

我已经尝试过这样的事情:

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

但是我的最终目标是触发所有侦听器功能,但这似乎不起作用。只是更新'value'属性也不会。

Answers:


142

创建一个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 });

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


2
是的,MDN创建和触发事件是一个很好的资源!
雅各布·霍利(JakubHolý)2016年

1
这是本机正确执行的方法。现在,所有浏览器均支持:caniuse.com/#feat=dispatchevent
Willem Mulder,

1
这是这个问题的真实答案。我们必须以现代方式实现这一目标。
КонстантинВан

1
我试图在IE11上做同样的事情,但是在尝试更改reactjs输入字段时它不起作用。 var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
Bodosko

3
为什么每个人都说这是最好的答案?根据链接的事件文档,即使当前版本的IE 仍不支持此功能。
jeff-h

96

在jQuery中,我主要使用:

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

2
这帮了我!我正在使用代码设置复选框的值(是否选中),无论我做什么,该事件都不会在IE中触发。我尝试了blur()focus()和其他一些东西。设置该值后,我称为触发器,并且还添加了一个click事件来调用触发器。它会引起多次火灾,但对我而言并不重要。在IE中,我通过代码添加了复选框,您必须在更改事件触发前单击它们两次。感谢您的提示。
达斯汀·戴维斯

6
作为更新,$(“#element”)。change(); 从jquery 1.0开始做同样的事情。
CookieOfFortune

3
请注意,这不会触发本地onchange。它只会在通过jQuery绑定的所有onchange侦听器上触发!
威廉·穆德

请帮忙吗?这些解决方案似乎都不为我工作.. stackoverflow.com/questions/51216332/...
加布

61

呃不要用eval做任何事情。好吧,有某些事情,但它们极为罕见。相反,您可以这样做:

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

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


3
评估JSON的目标;)
Aaron Powell

3
json2.js用于实现JSON对象化!JSON.parse已在现代浏览器中提供
jinglesthula 2012年

12
当通过设置“ onchange”附加了变更处理程序时,此技术有效。它不会生成触发w3c或Microsoft事件处理程序的“真实”事件。请参阅链接查看更多细节。
Stephen Nelson

6
我觉得现在这个答案已经过时,恶棍的答案使用new Event(...),并dispatchEvent是时下正确的解决方案,它似乎。
雅各布·霍利(JakubHolý)2016年

4
这个答案已经过时 ; 如果您Element.addEventListener以前用于处理事件,则上面的代码将不起作用。要以现代方式实现它,请参阅@Miscreant的答案。
КонстантинВан

23

出于某种原因,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仍然有效。


2
与我提供的示例相比,我更喜欢这种浏览器检测(通过对象检测)方法。
克里斯·麦克唐纳

对于Firefox 23,这不再起作用:“ element.dispatchEvent不是函数”
Oliver 2013年

4
各位Google员工,大家好。是2016年!现在我们写代码一样element.dispatchEvent(new Event('change', true, true)),而不是所有的晦涩难懂,大多是过时createEventinitEvent东西。
ericsoco's

3

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

javascript=>

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

2

取自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事件,就好像实际已发生更改一样。


1

如果使用此代码段添加所有事件,请执行以下操作:

//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<EVENTNAME>()where <EVENTNAME>是您的事件的名称,这将使用<EVENTNAME>



-4

如果您使用的是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方法,因此只需调用另外一行即可。

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

$get('elementId')._events

它允许您执行一些反射样式的工作,以找到要触发的正确事件处理程序。


1
我相信他想触发实际事件,而不是在事件触发时运行函数……我认为。大声笑
Kolten

-5

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

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

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

未定义不是函数。
赫里斯托·韦内夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.