問題:已知一個元素的類名是right並且這個元素的祖先元素的類名為parent,現在想通過原生JavaScript獲得這個類名為right的元素。
我的思路:利用遞歸。先判斷已知的祖先元素(題中的parent)是不是要找的目標元素(題中的right),如果是,則返回這個元素。否則,繼續查找這個祖先元素的子元素,並對子元素進行遞歸,直到找到目標元素。
下面是代碼:
html
<div class="parent"> <div class="left"> <img src="" alt=""> <p>段落</p> </div> <div class="right"> <div class="intro"> <h1>標題</h1> </div> </div> <p>另一個標題</p> </div>
js
//將NodeList轉換成Array function transformList(list) { var arr = []; for(var i = 0; i < list.length; i++) { arr.push(list[i]); } return arr; } //查找一個父節點下指定類名的子節點 function getParentdElement(parentNode, childName) { //如果父節點parentNode含有指定類名childName,這個節點就是目標節點 if (parentNode.className.search(childName) !== -1) { console.log("if------"); console.log(parentNode); return parentNode; } else { //父節點不含有指定類名childName,遞歸查找它的子節點。 var nodes = parentNode.childNodes; //將子節點的list轉換成標准數組並且過濾掉Text元素 nodes = transformList(nodes).filter(function(item){ if(item.nodeType !== 3) { return item; } else{ } }); //如果子節點數組中有值,則遞歸查找 if(nodes.length) { nodes.forEach(function(item) { getParentdElement(item, childName); }); } console.log("else------"); console.log(nodes); } } console.log(getParentdElement(document.querySelector(".parent"), "right"))
結果:
我感到很奇怪的是:在第六行"if--------"下面的輸出'<div class="right">...</div>'就是我想要的結果,也就是上面js代碼的"return parentNode",按理來說,代碼到此應該結束了,為什么后面有繼續執行了呢?我想這和我在遞歸里面用了forEach循環有關,但是我又不清楚具體是因為什么沒有停止代碼執行。於是我想到了第二種方案,就是把這個dom看成一棵多叉樹,利用遞歸把樹的節點放到棧或者數組里面,然后在對數組就行操作。
雖然想到了其他方法,但是我還是想知道這種思路是不是可行,或者是我想復雜了,有沒有其他更簡單的方法?
昨天晚上回去又做了一下,發現是我傻了,把問題想的復雜了,一直這樣用document.querySelector(“”),不知道也可以寫成document.querySelector(“”).querySelector(“”).querySelector(“”)...,所以昨天下午為了一個很小的問題繞了很大的圈子。實在不應該。但是如果不僅僅針對具體場景,單單想去這樣實現,我想還是有必要需要再去研究一下。
fighting!