UID: 20221218221939
aliases:
tags:
source:
cssclass:
created: 2022-12-18
如果我们要判定给定的一个节点是不是页面body
与元素节点,该如何判断呢?
一般来说, 一个HTML页面内只有一个body
元素
但是,如果我们非要在页面内写超过一个body
标签,会是什么结果呢?
比如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<body id="mybody">mybody</body>
</body>
<script>
window.onload = function () {
var body = document.getElementsByTagName('body');
console.log(body);
};
</script>
</html>
我们发现,它只查找到了我们定义了id的这个body元素,没有有包含页面顶级的body元素。会不会查找时只会返回我们书写的最后一个body呢?
再修改一下:
<body>
<body id="mybody">
<body id="mybody22">mybody</body>
</body>
</body>
这次我们嵌套了三层body:
并没有返回最后书写的#mybody22
,而是依旧返回了 #mybody
, 所以上述猜测是错误的。
我们把mybody
的 id 去掉再试试:
<body>
<body>
<body id="mybody22">mybody</body>
</body>
</body>
这次返回了mybody22
。
难道是因为加了id影响的?
我们再次修改:
<body id="root">
<body>
<body id="mybody22">mybody</body>
</body>
</body>
果然如此,查找时会返回第一个带有ID属性的body
元素。
等等,如果不是ID属性呢,如果时其他属性呢,我们再次修改:
<body name="top">
<body>
<body name="mybody22">mybody</body>
</body>
</body>
这次返回的也是顶级body
, 目前来看,使用getElementsByTagName
查找页面中所有的body
标签时,返回的应该时第一个具有具体属性的节点。并且,此时如果查看页面的Elements
树,发现页只保留了返回的该节点,页面中其他的body
标签节点消失了:
而根据MDN规范的表述,getElementsByTagName
预期应该返回所有符合条件的节点集合,根据我们以上的实验并不是如此,至少在传入的tagName为body
时。 所以说,这可能时浏览器实现中的一个Bug,或者,浏览器是根据其他某个规范执行的这样的操作,我们目前还不得而知。
这是不是个bug我们暂且放一边,因为我们真正关心的是:
不管我们写多少个body
, 页面中最终渲染出来只会保留一个
也就是说,当指定节点的tagName
是BODY
时,意味着它就是页面中唯一的那个body
标签:
function isBody(node) {
return node && node.tagName === 'BODY';
}
好了,这就是判断给定节点是否是body
节点的方法了。
在ueditor.js
的源码中,这个方法是这么写的:
isBody:function (node) {
return node && node.nodeType == 1 && node.tagName.toLowerCase() == 'body';
},
这里有两点:
- 他将tagName做了小写化处理,我觉得没必要,因为所有浏览器返回的
body
的tagName
都是大写的,直接用大写判断就可以了 - 他考虑到了节点的
nodeType
属性,我觉得也没有必要,因为符合tagName===BODY
的一定就是我们页面中那个body
元素,页面中其他类型的节点,不可能再有符合这个条件的。