设置假值与删除属性有什么区别?

8
我正在阅读关于布尔属性的文章(链接),其中提到对于布尔属性(在这个例子中是<audio>loop 属性),无论设置什么值,它都将被认为是“真”。如果要真正设置为假,您不能像loop=false或使用JavaScript['loop']=false这样进行设置,而必须删除该属性,例如通过执行removeAttribute('loop')。这是正确的吗?
我一开始也相信它,但在Chrome中检查后,似乎将其设置为['loop']=false确实会使其被识别为假。不确定在跨浏览器考虑时这个事实有多稳定。不同浏览器之间是否存在差异?

我更喜欢使用“falsy”这个词。 - mplungjan
2
根据这个,有值存在被认为是真的,你最好采用这种方式而不是设置为假。- http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.4.2 - JohnP
4个回答

6

布尔属性在这里解释:

http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.4.2

一些属性扮演布尔变量的角色(例如OPTION元素的选中属性)。它们在元素的开始标签中出现意味着属性的值为“true”。它们的缺失意味着值为“false”。 布尔属性可以合法地只有单个值:属性本身的名称(例如selected="selected")。
因此,尽管一些浏览器可能会将字符串“false”解释为未设置值,其他浏览器可能不会决定使用该值(这是正确的行为)。实际上,据我所知(或认为),任何非空字符串通常都会将值设置为on/true(无论规范规定什么是合法值)。我认为这也是未定义的行为,因此这也可能会改变或在浏览器之间有所不同(不要依赖它)。
最重要的是,仅因为一两个浏览器可能偏离规范并不意味着您应该这样做。完全删除属性是正确的做法。

附录:仔细查看您的评论和问题后,我认为您可能对属性值存在一些困惑。在HTML中,attr=falseattr="false" 是完全相同的。除非需要消除值中包含空格的歧义,否则不需要在任何版本的HTML中使用引号。例如:

<input class=required>
<!-- This is fine -->

<input class=title required>
<!-- this is fine too, but "required" will be parsed as an attribute -->

<input class="title required">
<!-- To have two classes, we need the quotes -->

所有具有属性值的元素中的属性值都被视为字符串。换句话说,在HTML中没有像javascript中一样的真正布尔值(或null值)。


谢谢您的补充,但我知道在HTML中它们被解释为字符串。这就是为什么我提到JavaScript的原因。在JavaScript中,我可以做像['loop']=false这样的事情,而不需要在false周围加引号,这与['loop']='false'不同。您的回答有所帮助。 - sawa
@sawa:对于补充内容我很抱歉。我从未在JavaScript中看到过像['loop']=false这样的语法,也许应该是element.loop = false。不确定你从哪里得到了那个语法?我还看到你来自CT。我也是。对此我也很抱歉 :) - Wesley Murch
我看到了,你也在康涅狄格州。你的回答帮了我很多,我没有发现其中有问题。感谢你的帮助。 - sawa
@WesleyMurch 如果出现这种情况怎么办:父元素定义了 contenteditable,但子元素想要禁用它?如果我们移除该属性,它将从父元素“继承”可编辑的属性。 - rr-
好的,没关系:contenteditable不是布尔属性,而是一个枚举属性,可能的值为truefalse''。说起来真是不一致。 - rr-

1

为了日后需要的人:

loop=false 仍然是 true,除非完全删除整个 loop 属性。基本上,只有 loop 的存在才需要标签执行其他操作。您需要使用类似 jQuery 的东西来删除整个 loop 属性(或者至少这是我会做的)。现在,如果将另一个未定义的属性设置为 false,则可以将其识别为 false


1

audio元素是HTML5元素,因此关于其含义,您应该查阅HTML5草案。在这种情况下,请参阅WHATWG草案的开发人员版本中的布尔属性定义。它说,实际上,a)属性的存在或不存在确定DOM属性值是true还是false,并且b)作为文档要求,值必须为空或(不区分大小写)属性名称,在这种情况下为loop=''loop="loop"。在其他地方定义了引号围绕值的使用。

因此,浏览器需要识别loop=falseloop=looploop=true表示相同,但作者不得使用这样的结构,并且HTML5检查器会发出错误消息。

(基本上,您应该在HTML5的HTML序列化中仅使用loop,在XHTML序列化中使用loop="loop"。)

因此,如果您在JavaScript中有一个变量x,其值为audio元素对象,则x.loop的值为truefalse,而x.attributes ['loop'] .value 表示HTML标记中使用的值(通常本身并不重要)。

关于Firefox还存在进一步的复杂性:它似乎仍然不支持loop属性(请参见问题HTML5 Audio Looping)。这意味着如果您设置例如loop =“loop”,则x.attributes ['loop'] .value 将是loop,但Firefox甚至不设置x.loop(即,它是undefined),更不用说实现功能了。


感谢您为我的问题提供了详细的答案。 - sawa

0
你混淆了字符串和真正的布尔类型。Javascript 有一个布尔数据类型,只有两个可能的值 true 和 false(不带引号)。字符串可以包含任何文本,因此它们可以包含带引号的 "true" 和 "false"。将属性设置为非 null 和非 false 将产生 true,因此以下情况将发生:
var a = true; // true
var b = false; // false
var c = "true"; // true
var d = "false" // true
var e = null; // false;
var f = 0; // false
var g = 1; // true

注意与C语言的相似之处。

他实际上是在指HTML部分而不是JS。这个问题没有正确标记。 - JohnP
哦,是的,抱歉,误解了问题。 - user529758
嘿,不是我没有仔细阅读...而是它被标记为“javascript”! - user529758
我是通过 JavaScript 进行操作的,并且区分 false"false" - sawa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接