admin管理员组

文章数量:1318958

I have a form. I want to only allow form submit if the user checks precisely 4 out of 8 available checkboxes; and once the user checks 4 checkboxes I want to disable the remaining unchecked ones.

Should I add a hook to the click event? Or maybe the input event? Or perhaps the change event?

I'm overwhelemed by the amount of events that seem to duplicate each other's functionality.

I'm also confused by the documentation.

MDN docs about input:

For <input> elements with type=checkbox or type=radio, the input event should fire whenever a user toggles the control, per the HTML5 specification. However, historically this has not always been the case. Check patibility, or use the change event instead for elements of these types.

MDN docs about change:

Unlike the input event, the change event is not necessarily fired for each alteration to an element's value.

And below:

Depending on the kind of element being changed and the way the user interacts with the element, the change event fires at a different moment:

  • When the element is :checked (by clicking or using the keyboard) for <input type="radio"> and <input type="checkbox">;

MDN docs about click:

An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element.

Practice:

The below JS fiddle seems to hint that all 3 events are equivalent. Clicking the checkbox, clicking the label, focusing the checkbox and pressing space on keyboard seem to all fire all three events.

const checkbox = document.querySelector('input[type=checkbox]');
for (const event of ['input', 'click', 'change']) {
  checkbox.addEventListener(event, () => {
    log.textContent = `${event}\n${log.textContent}`
  })
}
<label>Toggle <input type="checkbox" name="" id="">
</label>
<pre id="log"></pre>

I have a form. I want to only allow form submit if the user checks precisely 4 out of 8 available checkboxes; and once the user checks 4 checkboxes I want to disable the remaining unchecked ones.

Should I add a hook to the click event? Or maybe the input event? Or perhaps the change event?

I'm overwhelemed by the amount of events that seem to duplicate each other's functionality.

I'm also confused by the documentation.

MDN docs about input:

For <input> elements with type=checkbox or type=radio, the input event should fire whenever a user toggles the control, per the HTML5 specification. However, historically this has not always been the case. Check patibility, or use the change event instead for elements of these types.

MDN docs about change:

Unlike the input event, the change event is not necessarily fired for each alteration to an element's value.

And below:

Depending on the kind of element being changed and the way the user interacts with the element, the change event fires at a different moment:

  • When the element is :checked (by clicking or using the keyboard) for <input type="radio"> and <input type="checkbox">;

MDN docs about click:

An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element.

Practice:

The below JS fiddle seems to hint that all 3 events are equivalent. Clicking the checkbox, clicking the label, focusing the checkbox and pressing space on keyboard seem to all fire all three events.

const checkbox = document.querySelector('input[type=checkbox]');
for (const event of ['input', 'click', 'change']) {
  checkbox.addEventListener(event, () => {
    log.textContent = `${event}\n${log.textContent}`
  })
}
<label>Toggle <input type="checkbox" name="" id="">
</label>
<pre id="log"></pre>

As per the docs change and input seem equivalent; click does not seem equivalent to the other 3 as per the docs but in practice it seems equivalent.

Do we really have 3 events that duplicate each other's functionality? Does it matter in any way which event I use?

Or am I missing something?

Share Improve this question asked Sep 19, 2019 at 17:50 user4385532user4385532
Add a ment  | 

2 Answers 2

Reset to default 7

These 3 events duplicate each other's functionality because you are looking at a checkbox which happens to be a special case.

For example, if you were to take a text field

  • The event input will fire whenever the text in an element is changed using the user interface.
  • The event change will fire (on most browsers) whenever the text element loses focus. It would only be triggered once instead of after every keystroke.
  • The event click will fire whenever a user clicks on the text field.

If we were to apply this to checkboxes (keeping in mind there is only one thing a checkbox can be changes into: either checked => unchecked orunchecked => checked)

  • The event input will fire whenever the checked state is changed using user interface.
  • The event change will fire whenever the checked state has changed in an element (or when the checkbox loses focus in IE).
  • The event click will fire after the check state has finished changing .

The 3 events have very similar functionality (almost duplicates) because they are all trying to do something different that functionally does the same thing on checkboxes. The only differences being subtle implementation details.

I would use click to avoid having issues from the user of diffrent browsers.

They are not duplicated. There are subtle differences.

change happens once the value or state changes, and the element loses focus.

$('input').on('change', function(){
  console.log('changed');
});
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="1">
<input type="text">

click happens once the element is clicked.

input happens IMMEDIATELY once the value or state changes, before it loses focus. This happens regardless of if the state changes as per a mouse or keyboard event. A checkbox can change state by clicking it, or focusing on it and hitting the spacebar. A click event would not catch the spacebar state change.

$('input').on('change', function(){
  console.log('changed');
});

$('input').on('input', function(){
  console.log('input');
});
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="1">
<input type="text">

To test the lack of focus change and the spacebar change on the checkbox, you can click the input box and then shift+tab to focus the checkbox to hit spacebar. It appears from the fiddle that for checkboxes, the change and input events both happen any time it changes, even without the focus being lost.

This differs from how the text field behaves. So there appears to be some behavioral differences between the two elements in when the events are generated. The checkboxes appear to follow a less strict implementation of the pattern, as opposed to input boxes.

本文标签: javascriptClick vs Input vs Change for checkboxesStack Overflow