企业微信网站开发公司,seo短视频网页入口引流在线观看网站,上海做网站最好的公司,浙江省住房城乡建设厅网站首页一、前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系#xff0c;通过jQuery我们可以轻松搞定#xff0c;但原生JS呢#xff1f;下面我将整理各种判断方法#xff0c;以供日后查阅。 二… 一、前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系通过jQuery我们可以轻松搞定但原生JS呢下面我将整理各种判断方法以供日后查阅。 二、祖孙关系 html div idancestordiv idparentdiv idsonson/div/div
/div
div idotherother/div common.js var ancestor document.getElementById(ancestor);
var parent document.getElementById(parent);
var son document.getElementById(son);
var other document.getElementById(other); 方法一通过Selection对象 /** 定义判断祖孙关系函数* param {HTMLElement} parentNode* param {HTMLElement} sonNode*/
var has function(parentNode, sonNode){
if (parentNode sonNode) return true;var selection window.getSelection(); selection.selectAllChildren(parentNode);var ret selection.containsNode(sonNode, false);return ret;
};// 调用
console.log(has(ancestor, son)); // 显示true
console.log(has(ancestor, other)); // 显示false 缺点仅仅FF支持其他浏览器一律无效 1. 执行 selection.selectAllChildren(parentNode) 时parentNode的内容会被高亮并且原来高亮的部分将被取消 2. chrome下 selection.containsNode()恒返回false 3. IE9~11下的Selection类型对象没有containsNode方法 4. IE5.5~8下没有Selection类型 关于IE下的[object Selection]和[object MSSelection]类型详细可浏览《JS魔法堂细说Selection和MSSelection类型》 1. IE11仅有[object Selection]类型 获取方式 document.getSelection() 或 window.getSelection() 2. IE9~10有[object MSSelection]和[object Selection]两种类型 获取[object MSSelection] document.selection 获取[object Selection] document.getSelection() 和 window.getSelection() 3. IE5.5~IE8仅有[object MSSelection]类型 获取方式 document.selection 注意document.selection是IE的特有属性。 方法二通过Range对象 var has function(parentNode, sonNode){
if (parentNode sonNode) return true;var r1 document.createRange(), r2 document.createRange();r1.selectNode(parentNode);r2.selectNode(sonNode);var startRet r1.compareBoundaryPoints(Range.START_TO_START, r2);var endRet r1.compareBOundaryPoints(Range.END_TO_END, r2);var ret startRet -1 endRet 1;return ret;
}; 缺点不兼容IE5.5~8IE9、FF和Chrome均支持 1. IE5.5~8没有 document.createRange() 方法 关于[object Range]、[object TextRange]和[object ControlRange]类型 首先明确的是[object Range]是符合W3C标准的而[object TextRange]和[object ControlRange]是IE独有的。 详细可浏览《JS魔法堂细说Range、TextRange和ControlRange类型》 1. 通过document.createRange()创建[object Range]对象 2. 通过window.getSelection().getRangeAt({unsigned int32} index)获取[object Range]对象 3. 通过document.selection.createRange()或document.selection.createRangeCollection()方法获取[object TextRange]对象并且无法像Range对象内容通过selectNode方法直接绑定到DOM片段中。 方法三通过contains方法 var has function(parentNode, sonNode){return parentNode.contains(sonNode);
};
console.log(has(ancestor, ancestor));// 返回true
console.log(has(ancestor, son));// 返回true
console.log(has(ancestor, other));// 返回false 优点简单直接 缺点兼容性问题 支持——chrome、 firefox9、 ie5、 opera9.64(估计从9.0)、safari5.1.7 不支持——FF 方法四通过compareDocumentPosition方法 var has function(parentNode, sonNode){
if (parentNode sonNode) return true;var rawRet parentNode.compareDocumentPosition(sonNode); var ret !!(rawRet 16);return ret;
}; compareDocumentPosition可以算是W3C标准中比较两节点位置关系的一大利器不仅可以判断祖孙关系还可以判断其他关系哦 var ret A.compareDocumentPosition(B); 返回值ret的意思如下 Bits Number Meaning 000000 0 元素一致 000001 1 节点在不同的文档或者一个在文档之外 000010 2 节点 B 在节点 A 之前 000100 4 节点 A 在节点 B 之前 001000 8 节点 B 包含节点 A 010000 16 节点 A 包含节点 B 100000 32 浏览器的私有使用 方法五递归遍历 var has function(parentNode, sonNode){
if (parentNode sonNode) return true;var p sonNode.parentNode;if (!p.ownerDocument){return false;} else if (p ! parentNode){return has(parentNode, p);}else{return true;}
} 优点所有浏览器均通用 缺点当节点层级深时效率较低。 综合方案一来自司徒正美http://m.cnblogs.com/57731/1583523.html?full1 //2013.1.24 by 司徒正美 function contains(parentEl, el, container) {// 第一个节点是否包含第二个节点//contains 方法支持情况chrome firefox9 ie5, opera9.64(估计从9.0),safari5.1.7if (parentEl el) {return true;
}if (!el || !el.nodeType || el.nodeType ! 1) {return false;}if (parentEl.contains ) {return parentEl.contains(el);}if ( parentEl.compareDocumentPosition ) {return !!(parentEl.compareDocumentPosition(el) 16);}var prEl el.parentNode;while(prEl prEl ! container) {if (prEl parentEl)return true;prEl prEl.parentNode;}return false;} 综合方案二来自Sizzle(https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L688) 注意Sizzle的contains版本是contains(ancestor,ancestor)返回false的。 // Element contains another
// Purposefully does not implement inclusive descendent
// As in, an element does not contain itself
contains hasCompare || rnative.test( docElem.contains ) ?function( a, b ) {var adown a.nodeType 9 ? a.documentElement : a,bup b b.parentNode;return a bup || !!( bup bup.nodeType 1 (adown.contains ?adown.contains( bup ) :a.compareDocumentPosition a.compareDocumentPosition( bup ) 16));} :function( a, b ) {if ( b ) {while ( (b b.parentNode) ) {if ( b a ) {return true;}}}return false;}; 综合方案三我那又长又臭的版本^_^ var rNative /[^{]\{\s*\[native code\]\s*\}/;
var docEl document.documentElement;
var contains rNative.test(docEl.contains) function(ancestor, descendant){if (ancestor descendant) return true;ancestor ancestor.nodeType 9 ? ancestor.documentElement : ancestor;return ancestor.contains(descendant);
} ||
rNative.test(docEl.compareDocumentPosition)
function(ancestor, descendant){if (ancestor descendant) return true;ancestor ancestor.documentElement || ancestor;return !!(ancestor.compareDocumentPosition(descendant) 16);
} ||
rNative.test(document.createRange)
function(ancestor, descendant){if (ancestor descendant) return true;var r1 document.createRange(), r2 document.createRange();r1.selectNode(ancestor.documentElement || ancestor);r2.selectNode(descendant.documentElement || descendant); var startRet r1.compareBoundaryPoints(Range.START_TO_START, r2);var endRet r1.compareBOundaryPoints(Range.END_TO_END, r2);
var ret startRet -1 endRet 1;
try{
r1.detach();
r2.detach();
}catch(e){}
return ret;} ||
function(ancestor, descendant){
if (ancestor descendant) return true;
var a ancestor.documentElement || ancestor;
var b (descendant.documentElement || descendant)[parentNode];
while(!!b){
if (a b) return true;
b b.parentNode;
}
return false;
}; 三、总结 尊重原创转载请注明来自http://www.cnblogs.com/fsjohnhuang/p/3931818.html^_^肥子John 如果您觉得本文的内容有趣就扫一下吧捐赠互勉 分类: JavaScript 好文要顶 关注我 收藏该文 ^_^肥仔John关注 - 85粉丝 - 707 加关注 1 0 « 上一篇JS魔法堂函数重载 之 获取变量的数据类型» 下一篇CSS布局水平居中 posted 2016-03-02 11:29 ^_^肥仔John 阅读(751) 评论(0) 编辑 收藏 刷新评论刷新页面返回顶部 注册用户登录后才能发表评论请 登录 或 注册访问网站首页。 【推荐】超50万VC源码: 大型工控、组态\仿真、建模CAD源码2018【推荐】加入腾讯云自媒体扶持计划免费领取域名服务器 最新IT新闻: · 苏宁宣布重磅福利“7天无理由退货”线上线下统一标准 · 兴趣降温 安卓厂商无意模仿iPhone X推出3D识别 · 乐视云更名新乐视云联仍未获云服务牌照 · 微软搜索引擎Bing改进航班 电影和比赛结果查询 · 彭博商业周刊硅谷悄然掀起中国技术人员回国潮 » 更多新闻... 最新知识库文章:· 步入云计算 · 以操作系统的角度述说线程与进程 · 软件测试转型之路 · 门内门外看招聘 · 大道至简职场上做人做事做管理 » 更多知识库文章... 公告 肥仔Johngithub 作品iScheme—Scheme解释器 本文转自 ^_^肥仔John博客园博客原文链接http://www.cnblogs.com/fsjohnhuang/p/3931818.html如需转载请自行联系原作者