亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

不排除元素的 DOM 遍歷

不排除元素的 DOM 遍歷

三國紛爭 2023-10-24 21:49:46
我正在創建一個簡單的腳本,它遍歷 DOM 并返回一個樹對象,其中包含在 DOM 中找到的元素。遞歸遍歷本身非常簡單,但我想要/需要跳過某些元素并包含其他元素。我該怎么做呢?這是我的 HTML:<div data-element="from-here">  <div>skip me</div>  <div>    <div data-element="awesome">awesome text</div>    <div data-element="collect-me">      awesome text      <div data-element="also-me">        other text        <div class="but-not-me">...</div>      </div>    </div>  </div></div>還有我的遞歸遍歷代碼:const root = document.querySelector('[data-element="from-here"]');function traverse(node) {  return {    element: node.dataset.element,    children: Array.from(node.querySelectorAll(':scope > div')).map(childNode => traverse(childNode)),  };}traverse(root);正如您所看到的,代碼查詢所有 div 元素,但我只需要帶有data-element屬性的元素。我不能只執行 `node.querySelectorAll(':scope > [data-element]') 因為這不會超出第一個 div。這就是我想要的結果:{  element: 'from-here',  children: [    {      element: 'awesome',      children: [],    },    {      element: 'collect-me',      children: [        {          element: 'also-me',          children: [],        }      ]    }  ]}任何幫助將不勝感激!
查看完整描述

3 回答

?
郎朗坤

TA貢獻1921條經驗 獲得超9個贊

使用Array.prototype.flatMap可以大大降低轉換的復雜性 -

  1. 如果節點沒有值data-element

  2. 不包含節點;僅包括其子項的結果。

  3. 否則(通過歸納)該節點確實具有data-element值。將其包含element在輸出中以及該節點的children.

上面的編號點對應于下面的源評論 -

const root = document.querySelector('[data-element="from-here"]');


const toTree = ({ dataset = {}, children = [] }) =>

  dataset.element === undefined              // 1

    ? Array.from(children).flatMap(toTree)   // 2

    : [ { element: dataset.element           // 3

        , children: Array.from(children).flatMap(toTree)

        }

      ]


console.log(toTree(root)[0])

<div data-element="from-here">

  <div>skip me</div>

  <div>

    <div data-element="awesome">awesome text</div>

    <div data-element="collect-me">

      awesome text

      <div data-element="also-me">

        other text

        <div class="but-not-me">...</div>

      </div>

    </div>

  </div>

</div>

請注意,上面我們沒有使用querySelectorAll,因為不需要額外的文檔查詢。然而,一些明顯的改進是 -

  1. 將樹的形狀定義為單獨的函數,branch

  2. 為重復任務定義一個助手,allToTree

const branch = (element = "", children = []) =>    // 1

  ({ element, children })


const allToTree = (nodes = []) =>                  // 2

  Array.from(nodes).flatMap(toTree)

toTree現在已經擺脫了復雜性。我們的意圖很明確,每個功能都易于編寫、測試和維護 -


const toTree = ({ dataset = {}, children = [] }) =>

  dataset.element === undefined

    ? allToTree(children)

    : [ branch(dataset.element, allToTree(children) ]


查看完整回答
反對 回復 2023-10-24
?
鴻蒙傳說

TA貢獻1865條經驗 獲得超7個贊

您可以使用Array.filter()它來過濾掉沒有屬性的元素data-element。


但為了包含包裝器 div,您可能data-element還需要添加屬性,如下所示。


const root = document.querySelector('[data-element="from-here"]');


function traverse(node) {

  if (node.dataset.element) {

    return {

      element: node.dataset.element,

      children: Array.from(node.querySelectorAll(':scope > div'))

        .filter(child => {

          return child.dataset.element || Array.from(child.children).some(grandChild => grandChild.dataset.element)

         // If element has dataset     or  The child has some children with dataset attribute

        })

        .map(childNode => traverse(childNode)),

    };

  } else if (Array.from(node.children).some(child => child.dataset.element)) {

    return Array.from(node.querySelectorAll(':scope > div')).filter(child => child.dataset.element).map(childNode => traverse(childNode))

  }

}


console.log(traverse(root));

<div data-element="from-here">

  <div>skip me</div>

  <div>

    <div data-element="awesome">awesome text</div>

    <div data-element="collect-me">

      awesome text

      <div data-element="also-me">

        other text

        <div class="but-not-me">...</div>

      </div>

    </div>

  </div>

</div>


查看完整回答
反對 回復 2023-10-24
?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

為什么不使用 usingnode.querySelectorAll(':scope [data-element]')來代替呢?這將覆蓋具有該屬性的所有元素,而不僅僅是第一層子元素。

這是一個小提琴: https: //jsfiddle.net/cp21ykng/2/或者我錯過了什么?


查看完整回答
反對 回復 2023-10-24
  • 3 回答
  • 0 關注
  • 175 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號