更改的选项并使用JavaScript触发事件

时间:2021-11-24 02:06:29

How can I change an HTML <select>'s option with JavaScript (without any libraries like jQuery), while triggering the same events as if a user had made the change?

如何使用JavaScript更改HTML

For example using following code, if I change the option with my mouse then an event triggers (i.e. onchange is run). However, when I change the option using JavaScript then it doesn't fire any event. Is it possible to fire trigger associated event handlers like onclick, onchange, etc., when an option is selected with JavaScript?

例如,使用以下代码,如果我用鼠标更改选项,则会触发事件(即运行onchange)。但是,当我使用JavaScript更改选项时,它不会触发任何事件。当使用JavaScript选择选项时,是否可以触发触发器关联的事件处理程序,如onclick,onchange等?

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true;' value="Change option to 2" />

http://jsfiddle.net/xwywvd1a/

http://jsfiddle.net/xwywvd1a/

7 个解决方案

#1


17  

Unfortunately, you need to manually fire change event. And Event Contructor will be the best solution.

不幸的是,您需要手动触发更改事件。而Event Contructor将是最佳解决方案。

var select = document.querySelector('#sel'),
    input = document.querySelector('input[type="button"]');
select.addEventListener('change',function(){
    alert('changed');
});
input.addEventListener('click',function(){
    select.value = 2;
    select.dispatchEvent(new Event('change'));
});
<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3' selected>Three</option>
</select>
<input type="button" value="Change option to 2" />

And of course, Event constructor is not supported on IE. So you may need to polyfill with this:

当然,IE上不支持Event构造函数。所以你可能需要用这个填充:

function Event( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
}

#2


9  

Fiddle of my solution is here. But just in case it expires I will paste the code as well.

我解决方案的小提琴就在这里。但是为了防止它过期我也会粘贴代码。

HTML:

HTML:

<select id="sel">
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" id="button" value="Change option to 2" />

JS:

JS:

var sel = document.getElementById('sel'),
    button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;

    // firing the event properly according to *
    // http://*.com/questions/2856513/how-can-i-trigger-an-onchange-event-manually
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent("change", false, true);
        sel.dispatchEvent(evt);
    }
    else {
        sel.fireEvent("onchange");
    }
});

sel.addEventListener('change', function (e) {
    alert('changed');
});

#3


4  

It is as simple as this:

这很简单:

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    sel.onchange();
});

But this way has a problem. You can't call events just like you would, with normal functions, because there may be more than one function listening for an event, and they can get set in several different ways.

但这种方式有问题。您不能像使用普通函数那样调用事件,因为可能有多个函数正在侦听事件,并且可以通过多种不同方式设置它们。

Unfortunately, the 'right way' to fire an event is not so easy because you have to do it differently in Internet Explorer (using document.createEventObject) and Firefox (using document.createEvent("HTMLEvents"))

不幸的是,触发事件的“正确方法”并不那么容易,因为你必须在Internet Explorer(使用document.createEventObject)和Firefox(使用document.createEvent(“HTMLEvents”))中做不同的事情。

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    fireEvent(sel,'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);
    }
}

#4


2  

The whole creating and dispatching events works, but since you are using the onchange attribute, your life can be a little simpler:

整个创建和调度事件都有效,但由于您使用的是onchange属性,因此您的生活可以更简单一些:

http://jsfiddle.net/xwywvd1a/3/

http://jsfiddle.net/xwywvd1a/3/

var selEl = document.getElementById("sel");
selEl.options[1].selected = true;
selEl.onchange();

If you use the browser's event API (addEventListener, IE's AttachEvent, etc), then you will need to create and dispatch events as others have pointed out already.

如果您使用浏览器的事件API(addEventListener,IE的AttachEvent等),那么您将需要创建和分派事件,就像其他人已经指出的那样。

#5


1  

Try this:

尝试这个:

<select id="sel">
 <option value='1'>One</option>
  <option value='2'>Two</option> 
  <option value='3'>Three</option> 
  </select> 


  <input type="button" value="Change option to 2"  onclick="changeOpt()"/>

  <script>

  function changeOpt(){
  document.getElementById("sel").options[1].selected = true;

alert("changed")
  }

  </script>

#6


1  

These questions may be relevant to what you're asking for:

这些问题可能与您要求的内容相关:

Here are my thoughts: You can stack up more than one call in your onclick event like this:

以下是我的想法:您可以在onclick事件中堆叠多个调用,如下所示:

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true; alert("changed");' value="Change option to 2" />

You could also call a function to do this.

您也可以调用函数来执行此操作。

If you really want to call one function and have both behave the same way, I think something like this should work. It doesn't really follow the best practice of "Functions should do one thing and do it well", but it does allow you to call one function to handle both ways of changing the dropdown. Basically I pass (value) on the onchange event and (null, index of option) on the onclick event.

如果你真的想调用一个函数并且两者的行为方式相同,我认为这样的事情应该有效。它并没有真正遵循“函数应该做一件事并且做得好”的最佳实践,但它确实允许您调用一个函数来处理两种更改下拉列表的方法。基本上我在onchange事件上的onchange事件和(null,index of option)上传递(值)。

Here is the codepen: http://codepen.io/mmaynar1/pen/ZYJaaj

这是codepen:http://codepen.io/mmaynar1/pen/ZYJaaj

<select id="sel" onchange='doThisOnChange(this.value)'>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
<input type="button" onclick='doThisOnChange(null,1);' value="Change option to 2"/>

<script>
doThisOnChange = function( value, optionIndex)
{
    if ( optionIndex != null )
    {
       var option = document.getElementById( "sel" ).options[optionIndex];
       option.selected = true;
       value = option.value;
    }
    alert( "Do something with the value: " + value );
}
</script>

#7


-1  

You can fire the event manually after changing the selected option on the onclick event doing: document.getElementById("sel").onchange();

您可以在更改onclick事件上的选定选项后手动触发事件:document.getElementById(“sel”)。onchange();

#1


17  

Unfortunately, you need to manually fire change event. And Event Contructor will be the best solution.

不幸的是,您需要手动触发更改事件。而Event Contructor将是最佳解决方案。

var select = document.querySelector('#sel'),
    input = document.querySelector('input[type="button"]');
select.addEventListener('change',function(){
    alert('changed');
});
input.addEventListener('click',function(){
    select.value = 2;
    select.dispatchEvent(new Event('change'));
});
<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3' selected>Three</option>
</select>
<input type="button" value="Change option to 2" />

And of course, Event constructor is not supported on IE. So you may need to polyfill with this:

当然,IE上不支持Event构造函数。所以你可能需要用这个填充:

function Event( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
}

#2


9  

Fiddle of my solution is here. But just in case it expires I will paste the code as well.

我解决方案的小提琴就在这里。但是为了防止它过期我也会粘贴代码。

HTML:

HTML:

<select id="sel">
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" id="button" value="Change option to 2" />

JS:

JS:

var sel = document.getElementById('sel'),
    button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;

    // firing the event properly according to *
    // http://*.com/questions/2856513/how-can-i-trigger-an-onchange-event-manually
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent("change", false, true);
        sel.dispatchEvent(evt);
    }
    else {
        sel.fireEvent("onchange");
    }
});

sel.addEventListener('change', function (e) {
    alert('changed');
});

#3


4  

It is as simple as this:

这很简单:

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    sel.onchange();
});

But this way has a problem. You can't call events just like you would, with normal functions, because there may be more than one function listening for an event, and they can get set in several different ways.

但这种方式有问题。您不能像使用普通函数那样调用事件,因为可能有多个函数正在侦听事件,并且可以通过多种不同方式设置它们。

Unfortunately, the 'right way' to fire an event is not so easy because you have to do it differently in Internet Explorer (using document.createEventObject) and Firefox (using document.createEvent("HTMLEvents"))

不幸的是,触发事件的“正确方法”并不那么容易,因为你必须在Internet Explorer(使用document.createEventObject)和Firefox(使用document.createEvent(“HTMLEvents”))中做不同的事情。

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    fireEvent(sel,'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);
    }
}

#4


2  

The whole creating and dispatching events works, but since you are using the onchange attribute, your life can be a little simpler:

整个创建和调度事件都有效,但由于您使用的是onchange属性,因此您的生活可以更简单一些:

http://jsfiddle.net/xwywvd1a/3/

http://jsfiddle.net/xwywvd1a/3/

var selEl = document.getElementById("sel");
selEl.options[1].selected = true;
selEl.onchange();

If you use the browser's event API (addEventListener, IE's AttachEvent, etc), then you will need to create and dispatch events as others have pointed out already.

如果您使用浏览器的事件API(addEventListener,IE的AttachEvent等),那么您将需要创建和分派事件,就像其他人已经指出的那样。

#5


1  

Try this:

尝试这个:

<select id="sel">
 <option value='1'>One</option>
  <option value='2'>Two</option> 
  <option value='3'>Three</option> 
  </select> 


  <input type="button" value="Change option to 2"  onclick="changeOpt()"/>

  <script>

  function changeOpt(){
  document.getElementById("sel").options[1].selected = true;

alert("changed")
  }

  </script>

#6


1  

These questions may be relevant to what you're asking for:

这些问题可能与您要求的内容相关:

Here are my thoughts: You can stack up more than one call in your onclick event like this:

以下是我的想法:您可以在onclick事件中堆叠多个调用,如下所示:

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true; alert("changed");' value="Change option to 2" />

You could also call a function to do this.

您也可以调用函数来执行此操作。

If you really want to call one function and have both behave the same way, I think something like this should work. It doesn't really follow the best practice of "Functions should do one thing and do it well", but it does allow you to call one function to handle both ways of changing the dropdown. Basically I pass (value) on the onchange event and (null, index of option) on the onclick event.

如果你真的想调用一个函数并且两者的行为方式相同,我认为这样的事情应该有效。它并没有真正遵循“函数应该做一件事并且做得好”的最佳实践,但它确实允许您调用一个函数来处理两种更改下拉列表的方法。基本上我在onchange事件上的onchange事件和(null,index of option)上传递(值)。

Here is the codepen: http://codepen.io/mmaynar1/pen/ZYJaaj

这是codepen:http://codepen.io/mmaynar1/pen/ZYJaaj

<select id="sel" onchange='doThisOnChange(this.value)'>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
<input type="button" onclick='doThisOnChange(null,1);' value="Change option to 2"/>

<script>
doThisOnChange = function( value, optionIndex)
{
    if ( optionIndex != null )
    {
       var option = document.getElementById( "sel" ).options[optionIndex];
       option.selected = true;
       value = option.value;
    }
    alert( "Do something with the value: " + value );
}
</script>

#7


-1  

You can fire the event manually after changing the selected option on the onclick event doing: document.getElementById("sel").onchange();

您可以在更改onclick事件上的选定选项后手动触发事件:document.getElementById(“sel”)。onchange();