惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
有赞技术团队
有赞技术团队
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Vercel News
Vercel News
IT之家
IT之家
MyScale Blog
MyScale Blog
博客园_首页
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
罗磊的独立博客

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
DOM小测28期 – DOM节点文档前后位置判断 « 张鑫旭-鑫空间-鑫...
张鑫旭,zhangxinxu · 2019-03-02 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8522
本文可全文转载,个人网站无需授权,只要保留原作者、出处以及文中链接即可,任何网站均可摘要聚合,商用请联系授权。

小测头图

一、题目与考察点

题目地址:https://github.com/zhangxinxu/quiz/issues/9

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

DOM小测28期题目

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

本次B站答疑直播在上午10:34分开始,持续约30分钟,有录播,可以直接点击下面的视频观看。

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

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

node.contains(otherNode)

返回布尔值,表示node是否包含otherNode,或者就是node本身。

例如:

document.documentElement.contains(document.body);    // 返回值是true
document.body.contains(document.body);               // 返回值是true
document.body.contains(document.documentElement);    // 返回值是false

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

其它

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

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);

实时效果如下,点击妹子图片,看看输出的结果是?

控制台输出结果如下:

iframe内外节点包含关系

如果想要知道iframe内外的包含关系,则需要使用另外的API:compareDocumentPosition()

三、任意位置判断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的文章。

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

例如:

container.onclick = function (event) {
  // event.target ...
}

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

event.target.tagName == 'IMG'  // true或false

所有浏览器都返回大写标签名,当然,如果你不放心(以后变了,或者遇到SB浏览器),可以更严格比对下:

/^img$/i.test(event.target.tagName)    // true或false
event.target.tagName.toLowerCase() == 'img'    // true或false

我们还可以使用nodeName进行判断,例如:

event.target.nodeName == 'IMG'    // true或false

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

event.target instanceof Image    // true或false

也是可以的。

五、答疑要点总结

  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之间直播答疑。

有兴趣参与的可以多多关注下。

以上~

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=8522

(本篇完)