一文详解Node.contain 函数兼容处理
作者:前端奶爸
前言
好久不写文章了,都不知道跟大家怎么打招呼了,新的一年开始,也应该收心,做一些文字的记录以及分享了。
先说下写这篇文章的由来吧,接到一个需求需要在项目中实现一个效果,就是点击其他区域隐藏dom的操作,试了很多的方式,感觉都不是特别合理,所以针对当前需求做了一个方法的实现,使用dom
原生方法 contains
进行判断当前点击的元素是否是指定父级的子级,然后进行判断是否隐藏指定元素。
具体业务逻辑方法就不在这里赘述了,主要讲下contains
方法。
contains方法
Node 接口的 contains()
方法返回一个布尔值,表示一个节点是否是给定节点的后代,即该节点本身、其直接子节点(childNodes)、子节点的直接子节点等。
otherNode
要测试的节点。
备注: otherNode
不是可选的,但是可以设置为 null
。
返回一个布尔值,如果 otherNode
包含在节点中会返回 true
,否则返回 false
。
如果 otherNode
参数为 null
,则 contains()
始终返回 false
。
下面的函数用来检查一个元素是否是 body 元素的后代元素。由于 contains
会包含元素自身,而确定 body 是否包含自身不是设计 isInPage
的意图,这种情况明确返回 false
。
function isInPage(node) { return (node === document.body) ? false : document.body.contains(node); }
Specification |
---|
DOM Standard # ref-for-dom-node-contains① |
Report problems with this compatibility data on GitHub
desktop | mobile | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | |
contains | 16Toggle history | 12Toggle history | 9Toggle history | 7Toggle history | 1.1Toggle history | 18Toggle history | 9Toggle history | 10.1Toggle history | 1Toggle history | 1.0Toggle history | 4.4Toggle history |
兼容处理
因为是原生方法,兼容性有限,所以针对公司的项目兼容需求,还需要进行兼容处理。具体代码如下:
const contains = (root, el) => { if (root.compareDocumentPosition) return root === el || !!(root.compareDocumentPosition(el) & 16); if (root.contains && el.nodeType === 1) { return root.contains(el) && root !== el; } while ((el = el.parentNode)) if (el === root) return true; return false; };
这段代码实现了一个检测节点是否存在于指定容器中的函数contains
,其中使用了三种不同的方式进行判断:
- 如果浏览器支持
compareDocumentPosition
方法,则直接使用该方法进行判断。首先判断root
节点是否等于el
节点,如果是,则返回true
;否则,使用compareDocumentPosition
方法判断el
节点是否在root
节点中,如果结果为16,则返回true
,否则返回false
。 - 如果浏览器不支持
compareDocumentPosition
方法,但支持contains
方法,则判断el
节点是否是一个元素节点(nodeType为1),如果是,则使用contains
方法判断el
节点是否在root
节点中,并且root
节点不等于el
节点,如果满足,则返回true
,否则返回false
。 - 如果浏览器既不支持
compareDocumentPosition
方法,也不支持contains
方法,则使用while
循环遍历el
节点的所有祖先节点,判断是否有节点等于root
节点,如果有,则返回true
,否则返回false
。
综合三种方式,可以实现在各种浏览器中兼容检测节点是否存在于指定容器中的功能。
总结
方法整体的实现难度不是很大,就是针对当前原生方法的不支持的内容进行补充,
以上就是一文详解Node.contain 函数兼容处理的详细内容,更多关于Node.contain 函数兼容的资料请关注脚本之家其它相关文章!