DOM小测28期直播答疑文字版整理

1、题目与考察点

题目地址:github.com/zhangxinxu/…html

题目内容以下(点击查看大图):html5

DOM小测28期题目

本题主要考察如何判断DOM节点文档先后位置,父子关系等。我看了下最后的回答,近9成的回答使用了很是啰嗦的方法,比例之高,实在出乎意料。实际上,本题有很是简单、寥寥数行就能实现的方法,只要你知道下面这两个颇有用的DOM原生API,一个是contains()方法,判断DOM元素或节点是否有包含关系;另一个是compareDocumentPosition()方法,更强悍的DOM或节点位置关系判断,不管是先后、内外仍是跨文档均可以。node

本次B站答疑直播在周六上午10:34分开始,持续约30分钟,有录播,能够点击这里观看,建议1.5倍速食用。git

2、DOM包含关系判断contains()

contains()方法是一个很古老的API,用来判断两个DOM节点之间的包含关系,语法以下:github

node.contains(otherNode)复制代码

返回布尔值,表示node是否包含otherNode,或者就是node自己。浏览器

例如:bash

document.documentElement.contains(document.body);    // 返回值是true
document.body.contains(document.body);               // 返回值是true
document.body.contains(document.documentElement);    // 返回值是false复制代码

此API兼容性良好,IE5就开始支持了,使用很是方便,咱们无需专门遍历祖先元素用判断两个节点之间的嵌套关系。app

其它

若是判断的两个节点元素是跨iframe文档的,则会被认为是false。例如咱们直接借助Blob动态建立一个非外链iframe,代码以下:ide

var htmlIframe = '<img id="img" src="https://.../mm.jpg" onclick="console.log(window.parent.document.body.contains(this))">';
var iframe = document.createElement('iframe');
var blob = new Blob([htmlIframe], { 'type': 'text/html'});
iframe.src = URL.createObjectURL(blob);
iframeBlob1.appendChild(iframe);复制代码

点击图片,能够看到控制台输出结果以下:wordpress

iframe内外节点包含关系

若是想要知道iframe内外的包含关系,则须要使用另外的API:compareDocumentPosition()

3、任意位置判断compareDocumentPosition

本题中图片DOM元素先后位置的比对彻底不须要写循环进行遍历,有现成的API能够实现咱们想要的效果,那就是Node.compareDocumentPosition API。

此API很有深度,我专门写了篇文章介绍这个API,可参见这里:“深刻Node.compareDocumentPosition API”。

例如:

var compareValue = img.compareDocumentPosition(compareImg);
if (compareValue == 2) {
  // compareImg在前
} else if (compareValue == 4) {
  // compareImg在后
} else if (compareValue == 0) {
  // 就是compareImg元素自身
} else {
  // 其它位置关系
}复制代码

若是compareValue2,则表示compareImgimg的前面;若是是4,则表示compareImgimg的后面。

由此咱们能够轻松判断点击图片和对比图片之间的文档位置关系,寥寥几行代码的事情。

不过须要注意的是,若是是判断其余非替换元素的位置关系,则不能使用数值比对,由于可能compareDocumentPosition()方法执行后的值是一个混合数值,例如:

// 返回值是 10,8 + 2
document.body.compareDocumentPosition(document.documentElement);
// 返回值是 20,16 + 4
document.documentElement.compareDocumentPosition(document.body)复制代码

咱们须要使用单个&符合和对应目标值进行与位运算的结果来断定,例如:

if (document.body.compareDocumentPosition(document.documentElement) & 2) {
   // document.documentElement在document.body前面
   // ...
}复制代码

若是不是很理解,能够访问我刚写的专门深刻介绍compareDocumentPosition的文章。

4、如何判断click元素是图片

例如:

container.onclick = function (event) {
  // event.target ...
}复制代码

业界用的比较多的方法是使用tagName值进行判断,以下:

event.target.tagName == 'IMG'  // truefalse复制代码

全部浏览器都返回大写标签名,固然,若是你不放心(之后变了,或者遇到SB浏览器),能够更严格比对下:

/^img$/i.test(event.target.tagName)    // truefalse复制代码
event.target.tagName.toLowerCase() == 'img'    // truefalse复制代码

咱们还能够使用nodeName进行判断,例如:

event.target.nodeName == 'IMG'    // truefalse复制代码

最后,在介绍一种对象类型判断方法,以下:

event.target instanceof Image    // truefalse复制代码

也是能够的。

5、答疑要点总结

  1. 包含关系推荐使用Node.contains()方法;
  2. 判断当前元素是不是IMG,能够 :
    event.target.tagName/nodeName == 'IMG'复制代码
    /^img$/i.test(event.target.tagName)复制代码
    event.target.tagName.toLowerCase() == 'img'复制代码
    event.target instanceof Image复制代码
  3. 先后节点关系判断使用Node.compareDocumentPosition()

关于直播答疑

每周三会在这个项目issues中发布小测题,依次CSS,JS和DOM,每周六上午10:00~11:00之间直播答疑。

有兴趣参与的能够多多关注下,免费的。

以上~

相关文章
相关标签/搜索