“输入”元素的“变更”和“输入”事件的区别

谁能告诉我 changeinput事件之间的区别是什么?

我使用 jQuery 来添加它们:

$('input[type="text"]').on('change', function() {
alert($(this).val());
})

它还可以使用 input而不是 change

也许在事件顺序相对于焦点的不同?

108414 次浏览
  • 在大多数浏览器中,当内容发生更改和 元素失去 focus。它基本上是变化的集合。它不会像在案例 input event中那样对每个单独的变化触发。

  • 当元素的内容发生变化时,input event会同步激发。因此,事件侦听器往往更频繁地触发。

  • 不同的浏览器并不总是同意是否应该为特定类型的交互触发更改事件

根据 这篇文章:

  • 当通过用户界面更改元素的文本内容时,发生 oninput 事件。

  • 当选择、选中状态或元素 已经变了的内容时,发生 onchange 。在某些情况下,只有当元素失去焦点或者按下 return(Enter)键并且值已经更改时,才会发生这种情况。Onchange 属性可以与 <input><select><textarea>一起使用。

译者:

  • oninput : 文本内容的任何更改
  • onchange :
    • 如果是 <input />: 改变 + 失去焦点
    • 如果是 <select>: 更改选项

$("input, select").on("input", function () {
$("pre").prepend("\nOn input. | " + this.tagName + " | " + this.value);
}).on("change", function () {
$("pre").prepend("\nOn change | " + this.tagName + " | " + this.value);
}).on("focus", function () {
$("pre").prepend("\nOn focus | " + this.tagName + " | " + this.value);
}).on("blur", function () {
$("pre").prepend("\nOn blur | " + this.tagName + " | " + this.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<select>
<option>Alice</option>
<option>Bob</option>
<option>Carol</option>
<option>Dave</option>
<option>Emma</option>
</select>
<pre></pre>

MDN 文档有一个明确的解释(不确定是什么时候添加的) :

当用户提交对元素值的更改时,将为 inputselecttextarea元素触发更改事件。与输入事件不同,对于元素值的每次更改,不一定触发更改事件.

Https://developer.mozilla.org/en-us/docs/web/api/htmlelement/change_event

这两个事件之间最显著的差异是 是什么导致了value变化对 <input>

根据 MDN:

<input><select><textarea>元素的 value被更改时,将触发 input事件。

也就是,

input触发 任何时候value发生变化。

change 稍微复杂一点:

当用户提交对元素的 value的更改时,将为 <input><select><textarea>元素触发 change事件。与 input事件不同,对于元素的 value的每次更改,不一定触发 change事件。

换句话说,

使用者改变 value时,change触发。

具体什么时候发射取决于 <input>type:

因为..。

  • “收音机”和“复选框”:
    • 当元素为 :checked时,通过键盘或鼠标单击
  • “日期”和“文件”:
    • 显式提交更改时,即选择日期或文件
  • “短信”:
    • 当元素在其值被更改但未提交之后失去焦点时

公平的警告,浏览器是变化无常的,并不总是在事件上达成一致。这确实是规范,但是,您 应该能够指望这些时机。

似乎这个问题已经成为我时不时探访的问题之一。我不喜欢为了简单的事情而看墙上的文字。所以我决定发布一个实用的答案。

使用下面的演示,可以检查触发了哪些事件以及以什么顺序触发。

screenshot of the demo

let eventsToListen = [
"focus",
"blur",
"input",
"change",
];
let inputs = Array.from(
document.querySelectorAll("#inputs :is(input, textarea, select)")
);
inputs.forEach(input => {
input.eventQueue = [];
let queueLimit = eventsToListen.length * 2;
let queueDisplay = input.closest("td").nextElementSibling;
eventsToListen.forEach(event => {
input.addEventListener(event, () => {
input.eventQueue.push(event);
if (input.eventQueue.length > queueLimit) {
Array(input.eventQueue.length - queueLimit).fill(null).forEach(
_ => input.eventQueue.shift()
);
}
queueDisplay.textContent = input.eventQueue.join(", ");
});
});
});
* {
margin: 0;
padding: 0;
box-sizing: inherit;
color: inherit;
font-size: inherit;
font-family: inherit;
line-height: inherit;
}
body {
font-family: sans-serif;
box-sizing: border-box;
background-color: hsl(0, 0%, 90%);
}
#inputs {
margin: 1em;
}
#inputs td {
padding: 0.1em;
}
#inputs td:nth-child(2) :not(input[type=radio]):not(input[type=checkbox]) {
width: 100%;
}
#inputs label {
display: table;
}
#inputs td:last-child {
font-style: italic;
font-size: 0.8em;
opacity: 0.7;
padding-left: 1em;
}
#notices {
margin: 1em;
}
#notices ul {
padding-left: 2em;
line-height: 2;
}
#notices > ul {
margin-top: 0.5em;
}
input[type=radio]:focus,
input[type=checkbox]:focus {
transform: scale(1.5);
}
<table id="inputs">
<tr>
<td>text</td>
<td><input type="text" /></td>
<td></td>
</tr>
<tr>
<td>number</td>
<td><input type="number" /></td>
<td></td>
</tr>
<tr>
<td>textarea</td>
<td><textarea></textarea></td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>
<select>
<option>-</option>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</select>
</td>
<td></td>
</tr>
<tr>
<td rowspan="2">radio</td>
<td>
<label><input type="radio" name="something" /> Option 1</label>
</td>
<td></td>
</tr>
<tr>
<td>
<label><input type="radio" name="something" /> Option 2</label>
</td>
<td></td>
</tr>
<tr>
<td style="padding-right: 0.5em">checkbox</td>
<td>
<label><input type="checkbox" name="something2" /> Option 1</label>
</td>
<td></td>
</tr>
</table>


<hr>


<div id="notices">
notice that:
<ul>
<li>"input" event can occur multiple times before a "change" event occurs on text/number/textarea</li>
<li>"input" and "change" event seem to occur together/sequentially on select</li>
<li>"input"/"change" event might occur multiple times before a "blur" event occurs on select
<ul>
<li>when arrow keys are used to select an option</li>
</ul>
</li>
</ul>
</div>