如何使用vanillaJS有效地找到html节点之间的关系

时间:2017-06-07 09:35:51

标签: javascript dom

我在DOM中的不同位置和深度处有几个html节点。 我需要根据它们在DOM中的位置对它们进行有效排序,而不管它们的深度如何。

它应该使用VanillaJS实现,没有jQuery等。

例如,给出以下树:

<body>
   <div>
      <div id="a1b"></div>
   <div>
      <div>
         <div id="c1d"></div>
      </div>
      <div id="e1f"></div>
   </div>
   <div id="g1h"></div>
</body>

假设我们有一个函数接收到具有随机顺序的id的四个html元素,该函数应该按照DOM中的出现顺序返回这些元素,即类似于此的数组:{ {1}}。

3 个答案:

答案 0 :(得分:1)

只需使用compareDocumentPosition

elements.sort(function(a, b) {
    var p = a.compareDocumentPosition(b);
    return Boolean(p & Node.DOCUMENT_POSITION_FOLLOWING)
         - Boolean(p & Node.DOCUMENT_POSITION_PRECEDING);
});

答案 1 :(得分:1)

Node.compareDocumentPositionhow jQuery does it,优先:

const nodes = [
    document.getElementById('a1b'),
    document.getElementById('c1d'),
    document.getElementById('e1f'),
];

nodes.sort((a, b) =>
    a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ?
        -1 : 1);

const shuffle = arr => {
    for (let i = 0; i < arr.length; i++) {
        const j = i + Math.floor(Math.random() * (arr.length - i));
        const t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    return arr;
};

const nodes = shuffle(Array.from(document.body.getElementsByTagName("*")));

console.log(nodes.map(node => node.nodeName));

nodes.sort((a, b) =>
    a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ?
        -1 : 1);

console.log(nodes.map(node => node.nodeName));
<div>
  <section>
    <header></header>
    <span></span>
    <footer></footer>
    <table><tbody><tr></tr></tbody></table>
  </section>
</div>

答案 2 :(得分:0)

我认为这是一个很好的方法:

var randomNodes = [document.getElementById('c1d'),document.getElementById('a1b'),document.getElementById('e1f')]
var sorted = document.querySelectorAll(randomNodes.map(el=>'#'+el.id).join(', '));
console.log(sorted);
//if you want standard array:
console.log([...sorted]);
<div>
      <div id="a1b"></div>
   <div>
      <div>
         <div id="c1d"></div>
      </div>
   </div>
   <div id="e1f"></div>