为什么 preventDefault on checkbox click event returns true 对于选中的属性?

Why does preventDefault on checkbox click event returns true for the checked attribute?

我只是好奇,需要对以下情况进行一些解释。

假设我有一个复选框类型的输入元素,它附加了一个事件监听器,用于监听点击事件。我阻止了复选框的默认行为并记录了复选框的选中状态,这将始终 return true。

复选框的视觉表示告诉我它没有被选中。所以我假设检查状态会 return 错误。我确定这一定很愚蠢,而且我肯定误解了这里的某些内容。有趣的是,我也在记录事件本身。在目标 属性 中,选中的 属性 设置为 false,正如我所期望的那样。

根据我的理解,阻止默认将取消事件而不停止传播,那么这里到底发生了什么?

如果有人能在这方面启发我,那就太好了。这是例子。

var checkbox = document.getElementsByTagName('input')[0],
    output = document.getElementById('output');

checkbox.addEventListener('click', function(evt) {
  evt.preventDefault();
  output.innerHTML = "Checkbox checked attribute is " + this.checked;
  console.log(this.checked, evt.target.checked);
  console.log(evt);
}, false);
<input type="checkbox" id="my-checkbox" />
<label for="my-checkbox">Checkbox with preventDefault().</label>
<div id="output"></div>

根据 w3schools“preventDefault() 方法取消事件,如果它是可取消的,意味着属于事件的默认操作不会发生。”点击事件是可取消的(可以这样勾选console.log("cancelable?"+ evt.cancelable);。 因此,据我了解,复选框对象的点击事件的默认行为是读取复选框的当前状态并在 true 和 false 之间交替,从而将其状态更改为已选中和未选中。简而言之,默认行为是切换;因此,preventDefault() 取消了该行为。

关于复选框 checked = true; unchecked = false。如果您尝试调试并逐步跟踪 eventListener,您会发现一旦进入其中 即使踩到 [,未选中的框也会变为“已选中” =35=]() 所以当你打电话给 console.log(this.checked, evt.target.checked); 时那个时候编译器你的框被“选中”,只有当 eventListener 完成执行时,复选框才会回到“未选中”状态。 由此我可以得出结论,如果有复选框 preventDefault()实际上是在事件侦听器中的所有调用都执行完之后才真正激活(执行).

实际上,click 处理程序中 checked 值的结果是 依赖于实现的

正如我在多个浏览器中测试的那样,在这种情况下 Chrome/Firefox/Safari/Opera 将始终 return 为真,但是如果您一直单击该复选框元素,IE/Edge 的行为会变得有点奇怪.

我在规范中找到了这一段,这可能是对这种不一致的解释:

Note: During the handling of a click event on an input element with a type attribute that has the value "radio" or "checkbox", some implementations may change the value of this property before the event is being dispatched in the document. If the default action of the event is canceled, the value of the property may be changed back to its original value. This means that the value of this property during the handling of click events is implementation dependent.

但是当我去掉preventDefault语句后,IE/Edge中的结果与其他浏览器一致,这让我很困惑。

所以我认为这不是 IE/Edge 的预期行为……因此我提交了 a bug on Microsoft Connect


毕竟,如果我们假定 Chrome 的行为符合标准,那么以下可能是一个合适的解释:

根据 HTML Spec, an input[type=checkbox] element's checkedness is restored at the canceled activation process, which comes after the event handlers according to the Activation 部分。所以在事件处理程序执行期间,元素的检查状态还没有恢复。

(规范没有明确规定取消激活步骤必须在所有事件处理程序之后;但很容易推断,否则无法确定事件的取消状态)