摘要:對于上面例子遍歷結(jié)果應(yīng)為則總是先遍歷當(dāng)前層級的所有節(jié)點(diǎn),只有當(dāng)當(dāng)前層級所有節(jié)點(diǎn)都遍歷結(jié)束后才會進(jìn)入下一層級。
我們一般可以采用DFS(深度優(yōu)先遍歷)和BFS(廣度優(yōu)先遍歷)來遍歷DOM樹
介紹 DFS & BFS我們來結(jié)合具體例子進(jìn)行分析,給出HTML代碼片段如下:
DFS總是先進(jìn)入下一級節(jié)點(diǎn),只有當(dāng)下一級沒有未遍歷的子節(jié)點(diǎn)時(shí)才會進(jìn)入到當(dāng)前層級的其它節(jié)點(diǎn)。對于上面例子DFS遍歷結(jié)果應(yīng)為:
root, container, sidebar, menu, main, post, copyright
BFS則總是先遍歷當(dāng)前層級的所有節(jié)點(diǎn),只有當(dāng)當(dāng)前層級所有節(jié)點(diǎn)都遍歷結(jié)束后才會進(jìn)入下一層級。對于上面例子BFS遍歷結(jié)果應(yīng)為:
root, container, sidebar, main, menu, post, copyrightDFS的具體實(shí)現(xiàn)
DFS主要采用遞歸實(shí)現(xiàn),依次遍歷節(jié)點(diǎn),如果遍歷到的節(jié)點(diǎn)有子節(jié)點(diǎn),則開始遍歷子節(jié)點(diǎn)
const DFSTraverse = (rootNodes, rootLayer) => { const roots = Array.from(rootNodes) while (roots.length) { const root = roots.shift() printInfo(root, rootLayer) // 如果有子節(jié)點(diǎn),直接遍歷子節(jié)點(diǎn),同時(shí)將層級加1 if (root.children.length) { DFSTraverse(root.children, rootLayer + 1) } } }BFS的具體實(shí)現(xiàn)
BFS采用隊(duì)列的思想,采用出隊(duì)的方式遍歷節(jié)點(diǎn),如果遍歷到的節(jié)點(diǎn)有子節(jié)點(diǎn),則將子節(jié)點(diǎn)入隊(duì)(這里處理節(jié)點(diǎn)層級的方式比DFS更復(fù)雜一些,因?yàn)檫@里將所有節(jié)點(diǎn)都放到了同一個(gè)數(shù)組中進(jìn)行處理)
const BFSTraverse = (rootNodes, rootLayer) => { const roots = Array.from(rootNodes) const rootsLayer = [] // 單用一個(gè)數(shù)組存放每個(gè)節(jié)點(diǎn)的的層級 // 初始化 for (let i = 0; i < roots.length; i++) { rootsLayer.push(rootLayer) } var rootIdx = 0 // 記錄當(dāng)前處理roots中的第幾個(gè)節(jié)點(diǎn),方便查找rootsLayer中對應(yīng)的層級 while (roots.length) { const root = roots.shift() // 出隊(duì) printInfo(root, rootsLayer[rootIdx]) // 如果有子節(jié)點(diǎn),將子節(jié)點(diǎn)放到roots隊(duì)列中 if (root.children.length) { Array.prototype.push.apply(roots, Array.from(root.children)) // 將當(dāng)前層級加1得到子節(jié)點(diǎn)的層級 rootLayer = rootsLayer[rootIdx] + 1 for (let i = 0; i < root.children.length; i++) { rootsLayer.push(rootLayer) } } // 處理下一個(gè)root節(jié)點(diǎn) rootIdx++ } }結(jié)果
先給大家補(bǔ)全代碼:
// 輸入節(jié)點(diǎn)信息 const printInfo = (node, layer) => { var str = "" for (let i = 1; i < layer; i++) { str += " " } console.log(`${layer}:${str}${node.tagName} .${node.className}`); } console.log("DFS *******************************"); DFSTraverse(document.querySelectorAll(".root"), 1); console.log("BFS *******************************"); BFSTraverse(document.querySelectorAll(".root"), 1);
上面例子的運(yùn)行結(jié)果為:
破解前端面試(80% 應(yīng)聘者不及格系列):從 DOM 說起
Javascript-ONLY DOM Tree Traversal - DFS and BFS?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/50672.html
摘要:對于上面例子遍歷結(jié)果應(yīng)為則總是先遍歷當(dāng)前層級的所有節(jié)點(diǎn),只有當(dāng)當(dāng)前層級所有節(jié)點(diǎn)都遍歷結(jié)束后才會進(jìn)入下一層級。 我們一般可以采用DFS(深度優(yōu)先遍歷)和BFS(廣度優(yōu)先遍歷)來遍歷DOM樹 介紹 DFS & BFS 我們來結(jié)合具體例子進(jìn)行分析,給出HTML代碼片段如下: DFS總是先進(jìn)入下一...
摘要:算法之深度優(yōu)先遍歷和廣度優(yōu)先遍歷背景在開發(fā)頁面的時(shí)候,我們有時(shí)候會遇到這種需求在頁面某個(gè)節(jié)點(diǎn)中遍歷,找到目標(biāo)節(jié)點(diǎn),我們正常做法是利用選擇器,或者,但在本文,我們從算法的角度去查找節(jié)點(diǎn),同時(shí)理解一下深度優(yōu)先遍歷和廣度優(yōu)先遍歷的原理。 JS算法之深度優(yōu)先遍歷(DFS)和廣度優(yōu)先遍歷(BFS) 背景 在開發(fā)頁面的時(shí)候,我們有時(shí)候會遇到這種需求:在頁面某個(gè)dom節(jié)點(diǎn)中遍歷,找到目標(biāo)dom節(jié)點(diǎn),...
什么是樹 現(xiàn)實(shí)中樹隨處可見;在計(jì)算機(jī)世界,樹就是一種分層結(jié)構(gòu)的抽象模型?! ∪缦聢D所示: 樹結(jié)構(gòu)的可以用在很多情景,就如下圖公司的組織架構(gòu),用樹就可以表達(dá)出來,如下圖: 組織架構(gòu)只是其中之一,比如族譜、省市等用樹的結(jié)構(gòu)形式展現(xiàn)是完全可以?! 涞男g(shù)語 樹有很多的術(shù)語,如下圖: 樹:n(n≥0)個(gè)節(jié)點(diǎn)所構(gòu)成的有限集合,當(dāng)n=0時(shí),稱為空樹; 節(jié)點(diǎn)的度:節(jié)點(diǎn)的子樹個(gè)數(shù),例如B節(jié)點(diǎn)的度就...
摘要:樹可謂是開發(fā)者最常碰到的數(shù)據(jù)結(jié)構(gòu)之一了要知道整張網(wǎng)頁就是一棵樹啊所以我們就來學(xué)習(xí)樹這一數(shù)據(jù)結(jié)構(gòu)吧在這篇文章中我們將創(chuàng)建一棵樹并且用兩種不同的方法來遍歷它深度優(yōu)先遍歷和寬度廣度優(yōu)先遍歷方法使用借助棧這一數(shù)據(jù)結(jié)構(gòu)來訪問樹的每個(gè)節(jié)點(diǎn)則借助了隊(duì) 樹可謂是web開發(fā)者最常碰到的數(shù)據(jù)結(jié)構(gòu)之一了. 要知道, 整張網(wǎng)頁就是一棵DOM樹啊 (Document Object Model ). 所以我...
摘要:樹中結(jié)點(diǎn)的最大層次稱為樹的深度或高度。二叉樹有深度遍歷和廣度遍歷,深度遍歷有前序中序和后序三種遍歷方法。二叉樹的前序遍歷可以用來顯示目錄結(jié)構(gòu)等中序遍歷可以實(shí)現(xiàn)表達(dá)式樹,在編譯器底層很有用后序遍歷可以用來實(shí)現(xiàn)計(jì)算目錄內(nèi)的文件及其信息等。 樹的簡介 棧、隊(duì)列、鏈表等數(shù)據(jù)結(jié)構(gòu),都是順序數(shù)據(jù)結(jié)構(gòu)。而樹是非順序數(shù)據(jù)結(jié)構(gòu)。樹型結(jié)構(gòu)是一類非常重要的非線性結(jié)構(gòu)。直觀地,樹型結(jié)構(gòu)是以分支關(guān)系定義的層次結(jié)...
閱讀 982·2023-04-25 23:55
閱讀 2710·2023-04-25 14:13
閱讀 3297·2019-08-26 13:47
閱讀 2972·2019-08-23 18:16
閱讀 628·2019-08-23 17:20
閱讀 3228·2019-08-23 16:55
閱讀 3146·2019-08-22 15:39
閱讀 3196·2019-08-20 18:10