首页 > 试题广场 >

dom 节点查找

[编程题]dom 节点查找
  • 热度指数:52268 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
查找两个节点的最近的一个共同父节点,可以包括节点自身

输入描述:
oNode1 和 oNode2 在同一文档中,且不会为相同的节点

function commonParentNode(oNode1, oNode2) {
   
    for(;!oNode1.contains(oNode2);oNode1=oNode1.parentNode){
       
    }
     return oNode1
}
编辑于 2019-10-21 16:19:25 回复(0)
找了很久都没找到contains的官方用法说明(就找到一个jQuery的)
W3C的标准是
element.compareDocumentPosition() 比较两个元素的文档位置。
 function commonParentNode(oNode1, oNode2) {
    while(oNode1){
        var compare = oNode1.compareDocumentPosition(oNode2);
        if(compare ===10){  return oNode2;}
        if(compare ===20){  return oNode1; }
        oNode1=oNode1.parentNode;
    }
}
如果不想判断谁包含谁的话可以直接if(compare ===20||compare ===0){return oNode1; }
发表于 2017-10-14 19:57:51 回复(0)
function commonParentNode(oNode1, oNode2) {
	return oNode1.contains(oNode2) && oNode1 || commonParentNode(oNode1.parentNode,oNode2);
}

发表于 2017-04-25 11:09:28 回复(0)

        function commonParentNode(oNode1oNode2) {
            var oNode1Parents = [oNode1];
            var oNode2Parents = [oNode2];
     
            while (oNode1.parentNode) {
                oNode1Parents.push(oNode1.parentNode);
                oNode1 = oNode1.parentNode;
            }
            while (oNode2.parentNode) {
                oNode2Parents.push(oNode2.parentNode);
                oNode2 = oNode2.parentNode;
            }
            var len1 = oNode1Parents.length;
            var len2 = oNode2Parents.length;
            for (var i = 0i < len1i++) {
                for(var j=0;jlen2;j++){
                    if(oNode1Parents[i]==oNode2Parents[j]){
                        return oNode1Parents[i];
                    }
                }
            }
        }
发表于 2017-03-19 10:20:22 回复(0)
function commonParentNode(oNode1, oNode2) {
    var n = null;
    if(oNode1.contains(oNode2)){
        return oNode1;
    }else if(oNode2.contains(oNode1)){
        return oNode2;
    }else{
        n = oNode1.parentNode;
        do{
            if(n.contains(oNode2)){
                return n;
            }else{
                n = n.parentNode;
            }
        }while(n !== null)
    } 
}

发表于 2015-08-14 18:55:04 回复(0)
//不用去递归
//也 不用管谁包含谁,只要随便找一个节点,直到某个祖先节点(或自己)包含另一个节点就行了。 oNode.contains(oNode)是等于true的
 function commonParentNode(oNode1, oNode2) {
    for(;oNode1;oNode1=oNode1.parentNode){
    	if(oNode1.contains(oNode2)){
    		return oNode1;
    	}
    }
} 

编辑于 2016-08-27 10:00:21 回复(22)
没看讨论前还不知道contains这个函数,用了很蠢的方法,大体思路就是用两个父节点数组,新节点与另一个父节点数组比较。
function commonParentNode(oNode1, oNode2) {
    var parentList1 = [oNode1];
    var parentList2 = [oNode2];
    var position1 = 0;
    var position2 = 0;
    var resultNode ;
    while(resultNode === undefined){
        var newNode;
        if(position1 <= position2){
            newNode = parentList1[position1].parentNode;
            position1 += 1;
            for(let i =0;i<parentList2.length;i++){
                if(parentList2[i]=== newNode){
                    resultNode = newNode;
                    break;
                }
            }
            parentList1.push(newNode);
        } else {
            newNode = parentList2[position2].parentNode;
            position2 += 1;
            for(let i =0;i<parentList1.length;i++){
                if(parentList1[i]=== newNode){
                    resultNode = newNode;
                    break;
                }
            }
            parentList2.push(newNode);
        }
    }
    return resultNode;
}

发表于 2020-03-10 01:20:04 回复(0)
//递归
function commonParentNode(oNode1, oNode2) {
        if(oNode1.contains(oNode2)){
            return oNode1;
        } else if(oNode2.contains(oNode1)){
            return oNode2;
        } else{
            return commonParentNode(oNode1.parentNode, oNode2);
        }
    }
//循环
function commonParentNode(oNode1, oNode2) {
        for( ; oNode1; oNode1 = oNode1.parentNode){
            if(oNode1.contains(oNode2)){
                return oNode1;
            }
        }
    } 

发表于 2017-02-22 13:42:17 回复(0)
function commonParentNode(oNode1, oNode2) {
    if(oNode1.contains(oNode2)){
        return oNode1;
    }else{
        return commonParentNode(oNode1.parentNode,oNode2);
    }
} 
验证一个节点是否包含另一个节点就好了吧,不必验证两次,反正如果是被包含的关系,往上爬的时候会遇到另一个节点的。
编辑于 2015-09-04 13:48:57 回复(19)
function commonParentNode(oNode1, oNode2) {
    if(oNode1.contains(oNode2)){
        return oNode1;
    }else if(oNode2.contains(oNode1)){
        return oNode2;
    }else{
        return arguments.callee(oNode1.parentNode,oNode2);
    }
}
发表于 2015-06-30 19:08:12 回复(10)
//三种情况
//1、oNode1为oNode2的最近父节点;
//2、oNode2为oNode1的最近父节点;
//3、oNode1和oNode2在同一层
function commonParentNode(oNode1, oNode2) {
    if(oNode1.contains(oNode2))
        return oNode1;
    else if(oNode2.contains(oNode1))
    	return oNode2;
    else
        return oNode1.parentNode;
}

编辑于 2016-07-26 22:23:45 回复(4)
    function commonParentNode(oNode1, oNode2) {
        var parent1 = [];   //用于存储包括oNode1的所有oNode1父节点
        parent1.push(oNode1);
        while(oNode1.parentNode){
            parent1.push(oNode1.parentNode);
            oNode1 = oNode1.parentNode;
        }
        while(oNode2){
            for(var i in parent1){
                if( parent1[i] == oNode2 ){
                    return oNode2;
                }
            }
            oNode2 = oNode2.parentNode;
        }
        return null;
    }

发表于 2015-09-04 22:49:58 回复(0)
有两个dom的节点,dom1,dom2
1.判断dom1节点是否包含dom2节点;包含则返回dom1,不包含继续向下运行;
2.判断dom2节点是否包含dom1节点;包含则返回dom2,不包含继续向下运行
3.通过其中一个节点dom1去获取该节点的父节点,dom_p
4.通过父节点dom_p去查dom_f的子节点,看dom2是否在父节点dom_f的子节点中
5.如果dom2在dom_f的子节点中,则dom_f是最近的父节点;
6.如dom2不在dom_f的子节点中,则以domf_f继续去查dom_f的父节点,重复1,2,3,4步骤最终得出父节点dom_f'
编辑于 2015-06-15 11:44:06 回复(1)

oNode1为全局变量  每次循环oNode1 = oNode1.parentNode

条件为oNode1.contains(oNode2)

满足条件就返回oNode1



编辑于 2021-06-30 19:39:58 回复(0)
function commonParentNode(oNode1, oNode2) {
    while (!oNode1.contains(oNode2)) oNode1 = oNode1.parentNode
    return oNode1
}

发表于 2020-05-19 18:54:14 回复(0)
function commonParentNode(oNode1, oNode2) {
    if(oNode1 === oNode2) return oNode1;
    if(oNode1.parentNode !== null) return commonParentNode(oNode1.parentNode, oNode2);
    if(oNode2.parentNode !== null) return commonParentNode(oNode1, oNode2.parentNode);
}
递归三行就写完了昂
编辑于 2016-08-04 18:32:19 回复(2)
function commonParentNode(oNode1, oNode2) {
    if (oNode1.hasChildNodes(oNode2)) {
        return oNode1;
    } else if (oNode2.hasChildNodes(oNode1)) {
        return oNode2;
    } else {
        return commonParentNode(oNode1.parentNode, oNode2.parentNode);
    }
}
先比较两个节点包含关系,如不相互包含,同时向上寻找各自父节点再比较,可减少时间复杂度
发表于 2016-02-25 20:28:00 回复(2)
function commonParentNode(oNode1, oNode2) {
    // 方法一:
    while(true) {
        oNode1 = oNode1.parentNode;
        if(oNode1.contains(oNode2)) {
            return oNode1;
        }
    }
}

function commonParentNode(oNode1, oNode2) {
    // 方法二:
    if(oNode1.contains(oNode2)) {
        return oNode1;
    } else {
        // 递归
        return commonParentNode(oNode1.parentNode, oNode2);
    }
}

发表于 2022-03-22 18:45:41 回复(0)
function commonParentNode(oNode1, oNode2) {
    while(!oNode1.contains(oNode2)){
        oNode1 = oNode1.parentNode;
    }
    return oNode1;
}
发表于 2021-03-09 13:53:27 回复(0)
为什么不用compareDocumentPosition,这个明明比contains强大,为什么通过不了
发表于 2016-05-22 21:28:00 回复(0)