Il semble que cette question soit devenue l'une de celles que je consulte de temps en temps. Je ne suis pas fan de lire des murs de texte pour des choses simples. J'ai donc décidé de poster une réponse pratique.
À l'aide de la démo suivante, on peut examiner quels événements sont déclenchés et dans quel ordre.
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>