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

问题描述 投票:0回答:5

有人能告诉我

change
input
事件之间的区别是什么吗?

我正在使用 jQuery 添加它们:

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

它也适用于

input
而不是
change

也许事件顺序相对于焦点有所不同?

javascript jquery events dom
5个回答
175
投票

根据这篇文章

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

  • onchange
    occurs when the selection, the checked state, or the contents of an element have changed.在某些情况下,它仅在元素失去焦点或按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>


34
投票
  • change
    event
    在大多数浏览器中触发,当内容被更改并且 元素失去
    focus
    。它基本上是变化的集合。它不会像这种情况那样为每一次变化而触发
    input
    event
    .

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

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


13
投票

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

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

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>


9
投票

TL;DR: 最大的区别是是什么导致了值的变化:

  • input
    事件触发任何值变化
  • change
    事件触发直接用户启动 值更改
    • (具体细节因输入类型而异)

这两个事件之间最显着的区别是是什么原因

value
<input>
上的变化。

根据MDN

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

换句话说,

input
随时
变化

value
有点复杂

当用户提交对元素的

change
的更改时,为
change
<input>
<select>
元素触发
<textarea>
事件。与
value
事件不同,
input
事件不一定会在每次更改元素的
change
.

时触发

换句话说,

value
用户更改
change
时触发。此外,
value
通常仅在结束值与起始值不同(顾名思义)时才会触发。

具体来说,对于

change
<input>
事件的确切时间取决于输入的
change
属性。总的来说:

  • 对于基于文本的输入类型(例如:
    type
    search
    text
    email
    等):
    • 当元素失去焦点时(模糊)。
  • 对于打开某种交互式菜单的输入(例如
    password
    file
    date
    等):
    • 当 UI 元素关闭时。
    • 如果该类型具有直接文本输入机制(如
      color
      ),那么它也会在每次输入文本时触发(例如,在每个键入的数字上)。
  • 对于交互式的非文本输入(例如
    date
    checkbox
    radio
    ):
    • 当元素在与其交互后处于新状态时(例如单击、拖动、键盘快捷键触发)。

有一些元素有自己的细微差别,但这些在一般情况下都是正确的。


3
投票

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

当用户提交对元素值的更改时,会为

range
input
select
元素触发 change 事件。 与输入事件不同,更改事件不一定会在每次更改元素值时触发

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

© www.soinside.com 2019 - 2024. All rights reserved.