【问题标题】:Click vs Input vs Change for checkboxes?单击 vs 输入 vs 更改复选框?
【发布时间】:2020-01-20 19:29:33
【问题描述】:

我有一个表格。如果用户准确地选中了 8 个可用复选框中的 4 个,我只想允许表单提交;一旦用户选中了 4 个复选框,我想禁用其余未选中的复选框。

我应该给click 事件添加一个钩子吗?或者input 事件?或者change 事件?

我对似乎重复彼此功能的事件数量感到不知所措。

我也对文档感到困惑。

MDN docs about input:

对于带有type=checkboxtype=radio<input> 元素,只要用户切换控件,HTML5 specification 就会触发input 事件。然而,从历史上看,情况并非总是如此。检查兼容性,或使用change 事件代替这些类型的元素。

MDN docs about change:

input 事件不同,change 事件不一定会在每次更改元素的value 时触发。

以下:

根据要更改的元素类型和用户与元素交互的方式,change 事件会在不同的时刻触发:

  • 当元素为:checked(通过单击或使用键盘)时,对于<input type="radio"><input type="checkbox">

MDN docs about click:

当指针位于元素内部时同时按下和释放定点设备按钮(例如鼠标的主鼠标按钮)时,元素会收到 click 事件。

练习:

下面的 JS fiddle 似乎暗示所有 3 个事件都是等价的。单击复选框、单击标签、选中复选框和按键盘上的空格键似乎都会触发所有三个事件。

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>

根据文档 changeinput 似乎是等效的;根据文档,click 似乎不等同于其他 3 个,但实际上它似乎等同。

我们真的有 3 个事件可以重复彼此的功能吗?我使用哪个事件有什么关系吗?

还是我错过了什么?

【问题讨论】:

    标签: javascript events checkbox click onchange


    【解决方案1】:

    它们没有重复。有细微的差别。

    change 一旦值或状态发生变化,元素就会失去焦点。

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

    click 在元素被点击后发生。

    input 一旦值或状态发生变化,在失去焦点之前立即发生。无论状态是否根据鼠标或键盘事件发生变化,都会发生这种情况。复选框可以通过单击它来更改状态,或者关注它并点击空格键。 click 事件不会捕获空格键状态更改。

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

    要测试没有焦点变化和复选框上的空格键变化,你可以点击输入框然后shift+tab来聚焦复选框并点击空格键。从小提琴中可以看出,对于复选框,更改和输入事件都会在它更改时发生,即使焦点没有丢失。

    这与文本字段的行为方式不同。因此,在事件生成时,这两个元素之间似乎存在一些行为差异。与输入框相反,复选框似乎遵循不太严格的模式实现。

    【讨论】:

    • A click event would not catch the spacebar state change. 根据我的小提琴,实际上它似乎确实抓住了空格键;我在我的 OP 中提到了这一点。
    • 修复了禁用的评论。不知道为什么我认为我记得那个行为。
    • To test the (...) spacebar change on the checkbox, you can click the input box and then shift+tab to focus the checkbox to hit spacebar. 很抱歉我自己重复了一遍,但再一次,如果我在你的 sn-p 中添加一个 click 监听器,那么click 似乎确实抓住了空格键!我单击输入,然后单击 shift+tab 以聚焦复选框,然后按空格键并记录事件!
    • 请阅读我回答的最后一段。复选框上这些事件的实现方式似乎与其他输入元素(例如文本框)的实现方式不同。
    • 好的,谢谢。我确实阅读了您回答的最后一段,但据我了解,最后一段讨论的是changeinput 而不是click。您的答案的另一段仍然说:`复选框可以通过单击它来更改状态,或者专注于它并点击空格键。单击事件不会捕获空格键状态更改。`我只是在解释为什么我(可能不正确?)理解您断言click 不会捕获复选框上的空格键。
    【解决方案2】:

    这 3 个事件相互复制了彼此的功能,因为您正在查看一个恰好是特殊情况的复选框。

    例如,如果您要获取一个文本字段

    • 只要使用用户界面更改元素中的文本,就会触发事件input
    • 只要文本元素失去焦点,事件change 就会触发(在大多数浏览器上)。它只会触发一次,而不是每次击键后触发。
    • 只要用户单击文本字段,就会触发事件click

    如果我们将此应用于复选框(请记住,复选框只能更改为一件事:checked =&gt; uncheckedunchecked =&gt; checked

    • 只要使用用户界面更改选中状态,就会触发事件input
    • 只要检查状态发生变化,事件change就会触发 在元素 (or when the checkbox loses focus in IE) 中。
    • 检查状态更改完成后,click 事件将触发。

    这 3 个事件具有非常相似的功能(几乎是重复的),因为它们都试图做一些不同的事情,在功能上在复选框上做同样的事情。唯一的区别是细微的实现细节。

    我会使用click 来避免来自不同浏览器的用户的问题。

    【讨论】:

      猜你喜欢
      • 2019-12-25
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      相关资源
      最近更新 更多