【问题标题】:Precedence when HTML form element attributes and properties conflictHTML 表单元素属性和属性冲突时的优先级
【发布时间】:2014-03-26 11:48:16
【问题描述】:

我注意到浏览器和不同类型的表单元素之间的行为差​​异,当表单元素的 DOM 属性设置为与来自同一元素的属性的当前状态冲突时。

http://jsfiddle.net/Ldf2s/7/

document.forms['foo'].bar.checked=false;
document.forms['foo'].bar.setAttribute("checked", "true");

document.forms['foo'].baz.value = 'prop value';
document.forms['foo'].baz.setAttribute("value", "attr value");

在 IE 9 中:文本输入和复选框的属性均胜出(显示“prop value”且未选中)

在 Chrome 中:属性胜过文本输入的属性(显示“prop value”)但复选框已选中。

为什么文本输入和复选框有区别,为什么只有 Chrome 才有区别?

优先级应该是什么?如果更改 DOM 属性,是否应该覆盖当前表单输入状态?

【问题讨论】:

  • "checked" 的行为类似于属性,而不是属性。您需要使用 .setAttribute("checked", "checked"),而不是 true/false。
  • 'checked' 属性的值无关紧要——只有它的存在与否。问题是关于 foo.checked 与 foo.setAttribute("checked")。

标签: javascript html internet-explorer google-chrome


【解决方案1】:

看看http://jsfiddle.net/Ldf2s/9/

<form name="foo">
    <input name="bar" type="checkbox" />
    <input name="baz" type="text"/>
</form>

<script>
setTimeout(function() {
    document.forms['foo'].bar.setAttribute("checked", "true");
}, 5000);

setTimeout(function() {
    document.forms['foo'].baz.setAttribute("value", "attr value");
}, 5000);
</script>

如果您运行该页面并且不触摸输入框,则 5 秒后该复选框将被选中并设置值。但是,如果您运行该页面并立即单击复选框并在文本输入中键入一些文本,则一旦经过 5 秒,这些值将不会被修改。

这里要理解的概念是dirty checkness flagdirty value flag

它们的作用是标记复选框和文本输入字段,以判断document.forms['foo'].bar.setAttribute("checked", "true");document.forms['foo'].baz.setAttribute("value", "attr value"); 是否影响相应输入的选中状态和值。

对于脏检查标志,the HTML5 spec says

每个输入元素都有一个checkedness,由checked IDL属性暴露。

每个输入元素都有一个布尔脏检查标志。如果为真,则称该元素具有脏检查性。脏检查标志必须在创建元素时初始设置为 false,并且当用户以更改检查的方式与控件交互时必须将其设置为 true。

checked 内容属性是一个布尔属性,它给出了输入元素的默认检查状态。添加检查内容属性时,如果控件没有脏检查,则用户代理必须将元素的检查设置为true;当检查内容属性被移除时,如果控件没有脏检查性,用户代理必须将元素的检查性设置为false。

因此,在上面的 JSFiddle 中,用户单击复选框的行为会停止 setAttribute 调用,从而影响复选框是否被选中。

但是,它也说

checked IDL 属性允许脚本操作输入元素的检查状态。在获取时,它必须返回元素的当前检查状态;并且在设置时,它必须将元素的检查性设置为新值,并且将元素的脏检查性标志设​​置为真

所以document.forms['foo'].bar.checked=false; 还应该具有阻止setAttribute 调用设置检查状态的效果,因为它也应该使脏检查标志为真。

但在 Chrome 中检查的值发生了变化,因此与 HTML5 规范不一致。


HTML5 规范对文本输入值也有类似的要求,即当用户更改值或 value 属性以编程方式设置时设置为 true 的脏值标志。

在这种情况下,Chrome 的行为似乎是正确的,可能是因为在描述脏值标志时明确要求在以编程方式设置值属性时设置脏值标志,而脏检查标志的等效描述没有有匹配的评论。该要求仅在上面的引用中单独给出。

【讨论】:

  • 差异一定是Chrome不认为checked=false语句使复选框变脏,因为复选框没有从初始状态改变。 (也许优化了无操作?)IE 必须无条件地将分配视为设置脏检查标志。请参阅此修改:jsfiddle.net/Ldf2s/11 - 如果最初选中该复选框,则对 checked=false 的调用将阻止后续 setAttribute("checked") 调用选中该框。
  • 不确定这是否真的是 Chrome 中的错误 - 取决于您如何定义“设置”。
【解决方案2】:

浏览器有所不同,部分原因是对所涉及的 DOM 功能没有准确的、基于共识的定义。在 HTML5 中,这是标准化的:input element 被定义为 checked 属性(他们称之为“IDL 属性”)描述了实际的检查状态(受用户操作和 JavaScript 代码的影响),而defaultChecked 属性对应于HTML 属性checked,它设置了initial 检查。

在问题的示例代码中,checked 属性设置为值false,这不会改变任何内容(它是初始值,在没有checked 属性的情况下)。然后设置checked 属性,从而设置defaultChecked 属性,但这不会改变检查状态。

因此,Chrome 不支持 HTML5 草案。这在形式上只是一个特性,因为到目前为止还没有经过批准的规范,但实际上,它可以被描述为一个错误。

对于文本输入框input type=text,不存在这样的问题,因为value属性更直接地反映了value属性(没有单独的defaultValue属性)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多