javascript - Diferența dintre evenimentul "change" și "input" pentru un element `input`
Poate cineva să-mi spună care este diferența dintre evenimentele change și input?
Folosesc jQuery pentru a le adăuga:
$('input[type="text"]').on('change', function() {
alert($(this).val());
})
Funcționează și cu input în loc de change.
Poate o diferență în ordonarea evenimentelor în raport cu focalizarea?
Răspuns #1
Conform acestei postări:
Evenimentul
oninputapare atunci când conținutul textului unui element este modificat prin intermediul interfeței utilizatorului.onchangeapare atunci când selecția, starea bifată sau conținutul unui element s-a schimbat. În unele cazuri, apare doar atunci când elementul își pierde focalizarea sau la apăsarea tastei return (Enter) și valoarea a fost modificată. Atributul onchange poate fi utilizat cu:<input>,<select>și<textarea>.
Rezumat:
oninput: orice modificare făcută în conținutul textuluionchange:- Dacă este un
<input />: schimbă + pierde focusul
- Dacă este un
- Dacă este un
<select>: schimbă opțiunea
$("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>Răspunsul #2
Evenimentul
changese declanșează în majoritatea browserelor atunci când conținutul este modificat și elementul pierdefocus. Practic, este un agregat de modificări. Nu se va declanșa pentru fiecare modificare în parte, așa cum se întâmplă în cazul evenimentuluiinput.Evenimentul
inputse declanșează sincron la modificarea conținutului elementului. Astfel, ascultătorul de evenimente tinde să se declanșeze mai frecvent.Browserele diferite nu sunt întotdeauna de acord dacă trebuie declanșat un eveniment de schimbare pentru anumite tipuri de interacțiuni
Răspunsul #3
Se pare că această întrebare a devenit una dintre acele întrebări pe care le vizitez din când în când. Nu sunt fan să citesc ziduri de text pentru lucruri simple. Așa că am decis să postez un răspuns practic.
Folosind următorul demo, se poate examina care evenimente sunt declanșate și în ce ordine.
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>Răspunsul #4
Rezumat: Cea mai mare diferență este ce cauzează schimbarea valorii:
- Evenimentele
inputse declanșează la orice modificare de valoare Evenimentele
changese declanșează la modificările de valoare inițiate direct de utilizator- (Detaliile exacte ale acestuia variază între tipurile de intrare)
Cea mai semnificativă diferență între aceste două evenimente este ce determină schimbarea value pe <input>.
Conform MDN:
Evenimentul
inputse declanșează atunci cândvalueal unui element<input>,<select>sau<textarea>a fost modificat.
Cu alte cuvinte, input se declanșează de fiecare dată când value se schimbă.
schimbare este puțin mai complicată:
Evenimentul
changeeste declanșat pentru elementele<input>,<select>și<textarea>atunci când o modificare avaluea elementului este confirmată de utilizator. Spre deosebire de evenimentulinput, evenimentulchangenu este neapărat declanșat pentru fiecare modificare avaluea unui element.
Cu alte cuvinte, change se declanșează atunci când utilizatorul schimbă valoarea. În plus, change se declanșează, în general, doar atunci când valoarea finală este diferită de cea inițială (așa cum sugerează și numele său).
Pentru <input> în mod specific, momentul exact al evenimentului change depinde de atributul type al inputului. În general:
Pentru tipurile de intrare bazate pe text (de exemplu:
search,text,email,passwordetc.):- Când elementul pierde focusul (la pierderea focalizării).
Pentru intrări care deschid un fel de meniu interactiv (de exemplu file, date, color, etc.):
- Când elementul UI este închis.
date), atunci acesta declanșează și la fiecare introducere de text (de exemplu, la fiecare cifră tastată).Pentru intrările non-textuale care sunt interactive (de exemplu checkbox, radio și range):
- Când elementul rămâne într-o stare nouă după interacțiunea cu el (de exemplu, clic, glisare, declanșarea unei scurtături de la tastatură).
Există câteva elemente cu nuanțele lor proprii, dar acestea sunt adevărate în cazul general.
Demonstrație Interactivă
new Vue({
el: '#app',
data: {
inputs: [],
changes: [],
types: ['text', 'email', 'color', 'file', 'date', 'range'],
},
methods: {
logEvent(e, index) {
this.$set(this[e.type + 's'], index, e.target.value);
},
},
});<link href="https://unpkg.com/bootstrap@4/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@2/dist/vue.min.js"></script>
<div id="app">
<div class="container mw-100 py-3">
<div v-for="(type, i) in types" class="row mb-2">
<div class="col-2">
<span>{{ type.charAt(0).toUpperCase() + type.slice(1) }}:</span>
</div>
<div class="col-5">
<input :type="type" @input="logEvent($event, i)" @change="logEvent($event, i)" />
</div>
<div class="col-5">
<div class="row">
<div class="col-6 text-break">
<span>Input: <span style="color: red">{{ inputs[i] }}</span></span>
</div>
<div class="col-6 text-break">
<span>Change: <span style="color: blue">{{ changes[i] }}</span></span>
</div>
</div>
</div>
</div>
</div>
</div>