我很好奇,需要对以下情况作出解释。
假设我有一个类型为checkbox的输入元素,并附加了一个eventlistener,侦听click事件。我阻止了复选框的默认行为,并记录复选框的选中状态,它将始终返回true。
复选框的直观表示告诉我它没有被选中。所以我假设检查状态将返回false。我相信这肯定是愚蠢的,我绝对会误解这里的事情。有趣的是,我也在记录事件本身。在目标属性内部,checked属性设置为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>
答案 0 :(得分:8)
实际上,checked
处理程序中click
值的结果是依赖于实现。
正如我在多个浏览器中测试的那样,在这种情况下,Chrome / Firefox / Safari / Opera将始终返回true,但如果您继续单击该复选框元素,IE / Edge的行为会有点奇怪。
我在规范中找到了这一段,这可能是对这种不一致的解释:
注意:在处理具有值为“radio”或“checkbox”的type属性的input元素上的click事件期间,某些实现可能会更改此属性的值之前事件正在文档中发送。如果取消事件的默认操作,则可以将属性的值更改回其原始值。这意味着在处理点击事件期间此属性的值取决于实现。
但是当我删除preventDefault
语句时,IE / Edge中的结果与其他浏览器一致,这让我感到困惑。
所以我认为这不是IE / Edge的预期行为......因此我提交了a bug on Microsoft Connect。
毕竟,如果我们认为Chrome的行为符合标准,那么以下内容可能是合适的解释:
根据HTML Spec,在取消的激活过程中恢复input[type=checkbox]
元素的检查,该过程位于事件处理程序之后,根据Activation部分。因此,在执行事件处理程序期间,元素的检查性尚未恢复。
(规范没有明确说明已取消的激活步骤必须在所有事件处理程序之后;但很容易推断,否则无法确定事件的取消状态)
答案 1 :(得分:2)
根据w3schools“preventDefault()方法取消该事件,如果它是可取消的,这意味着不会发生属于该事件的默认操作。” click事件是可取消的(你可以像这样查看 console.log(“cancelable?”+ evt.cancelable); 。 因此,根据我的理解,复选框对象的click事件的默认行为是读取复选框的当前状态,并在true和false之间切换,从而将其状态更改为选中和取消选中。简而言之,默认行为是切换;因此,preventDefault()取消了该行为。
关于复选框 checked = true; unchecked = false 。如果你尝试调试并逐步跟踪eventListener,你会看到一旦你进入它,即使在踩到 evt.preventDefault()之后,未经检查的框也会被“检查” / em> 所以当你为编译器调用 console.log(this.checked,evt.target.checked); 时,你的框被“选中”,只有当eventListener完成执行时,复选框才会返回“未选中”状态。从中我可以得出结论,如果复选框 ,则在所有调用之后的最后一次调用时,实际上都会激活(执行)preventDefault()事件监听器已执行 。