`input` 元素的“更改”和“输入”事件之间的区别

Posted

技术标签:

【中文标题】`input` 元素的“更改”和“输入”事件之间的区别【英文标题】:Difference between "change" and "input" event for an `input` element 【发布时间】:2013-06-07 12:04:03 【问题描述】:

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

我正在使用 jQuery 来添加它们:

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

它也适用于 input 而不是 change

相对于焦点的事件顺序可能有些不同?

【问题讨论】:

rakshasingh.weebly.com/1/post/2012/12/… 请注意,旧版浏览器不支持 oninput。您可以使用:onchange、onpaste 和 onkeyup 作为解决方法。 PS:oninput 事件在 IE9 中也有问题,删除时不会触发。 input 更频繁地触发,例如在按键之后,而 change 基本上在输入模糊并且值不是输入焦点时的值时触发。 input 事件也捕获粘贴。见***.com/questions/15727324/… TLDR:输入时输入触发,点击外部时改变触发 【参考方案1】:

根据this post:

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

onchange 在元素的选择、选中状态或内容发生变化时发生。在某些情况下,它仅在元素失去焦点或按下 return (Enter) 并且值已更改时发生。 onchange 属性可用于:<input><select><textarea>

TL;DR:

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>

【讨论】:

我仍然不清楚两者之间的区别。从您的描述来看,它们听起来非常相似。 @JustinMorgan 就像在 JSFiddle 示例中一样,onchange 出现在“元素失去焦点时”,而 oninput 出现在每次文本更改时。 不同的是oninput事件是在元素的值发生变化后立即发生,而onchange是在元素失去焦点、内容发生变化后发生。 换句话说,当任何字符被更改、删除或添加时,“输入”会立即触发,而在控件失去焦点后评估“更改”并且仅在值发生更改时才会发生 我刚刚尝试过使用 Chrome。 onchange 也会在您仍然专注时按 Enter 触发。【参考方案2】:

change event 在大多数浏览器中在内容发生更改时触发 元素丢失focus。它基本上是变化的集合。它不会像 input event 那样为每一个更改触发。

input event 在元素内容更改时同步触发。因此,事件侦听器往往会更频繁地触发。

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

【讨论】:

我认为输入事件不能保证同步触发。 另外,所有浏览器的当前版本都支持input事件。 @TimDown,这就是我说浏览器支持不同的原因。不是每个人都拥有每个浏览器的当前版本。 @TimDown 是否同步触发? @SurajJain:说实话,我不确定。【参考方案3】:

这两个事件之间最显着的区别是是什么导致&lt;input&gt; 上的value 发生变化。

根据MDN:

&lt;input&gt;&lt;select&gt;&lt;textarea&gt; 元素的 value 发生更改时,将触发 input 事件。

又名,

input 触发任何时候value 更改。

change 稍微复杂一点:

当用户提交对元素的value 的更改时,会为&lt;input&gt;&lt;select&gt;&lt;textarea&gt; 元素触发change 事件。与input 事件不同,change 事件不一定会在每次更改元素的value 时触发。

换一种说法,

用户更改valuechange触发。

它何时触发取决于&lt;input&gt;type

为了……

“收音机”和“复选框”: 当元素为:checked时,通过键盘或鼠标点击 “日期”和“文件”: 当明确提交更改时,即。选择日期或文件 “文本”: 当元素在其值更改后失去焦点但未提交时

关于浏览器变化无常的公平警告,并且并不总是就事件达成一致。然而,这确实是规范,您应该能够依靠这些时间安排。

【讨论】:

【参考方案4】:

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

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

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>

【讨论】:

【参考方案5】:

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

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

https://developer.mozilla.org/en-US/docs/Web/API/htmlElement/change_event

【讨论】:

以上是关于`input` 元素的“更改”和“输入”事件之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

KeyPress 和KeyDown KeUp之间的区别

input输入框的oninput和onchange事件

实时监听input输入框value的变化:

处理输入类型不适用的更改事件?

如何将“更改”事件委托给正文的输入元素?

blur和click事件冲突