根据DOM在DOM中的位置对包含DOM元素的数组进行排序

use*_*278 8 html javascript arrays jquery dom

上下文

我构建了一个jQuery插件,我目前正在以一种方式将DOM元素存储在一个数组中,主要是为了能够在这些元素旁边存储更多信息,而不必使用不那么快data().

该数组看起来像:

[
    { element: DOMElement3, additionalData1: …, additionalData2: … },
    { element: DOMElement1, additionalData1: …, additionalData2: … },
    { element: DOMElement2, additionalData1: …, additionalData2: … },
]
Run Code Online (Sandbox Code Playgroud)

这个插件的工作方式阻止我以可预测的顺序将这些元素推送到数组,这意味着DOMElement3实际上可以找到低于DOMElement2s 的索引.

但是,我需要按照它们包含的DOM元素在DOM中出现的顺序对这些数组元素进行排序.前面的示例数组一旦排序,将如下所示:

[
    { element: DOMElement1, additionalData1: …, additionalData2: … },
    { element: DOMElement2, additionalData1: …, additionalData2: … },
    { element: DOMElement3, additionalData1: …, additionalData2: … },
]
Run Code Online (Sandbox Code Playgroud)

这是当然,如果DOMElement1之前出现DOMElement2在DOM,和DOMElement2DOMElement3.

丢弃的解决方案

jQuery add()方法以与DOM中出现的顺序相同的顺序返回一组DOM元素.我可以使用它,但要求是我使用jQuery集合 - 这意味着我必须重构上述插件的大部分以使用不同的存储格式.这就是为什么我认为这是最后的解决方案.

另一种方法?

我想象一下,map()与每个DOM元素绑定的一种全局DOM索引可以完成这个技巧,但似乎没有这样的"全局DOM索引".

你能想到什么方法?(如果编写代码,欢迎使用vanilla JS和jQuery.)

Nie*_*sol 14

有一个非常有用的函数compareDocumentPosition,它根据两个元素相对于彼此的位置返回一个数字.您可以在.sort回调中使用它:

yourArray.sort(function(a,b) {
    if( a === b) return 0;
    if( !a.compareDocumentPosition) {
        // support for IE8 and below
        return a.sourceIndex - b.sourceIndex;
    }
    if( a.compareDocumentPosition(b) & 2) {
        // b comes before a
        return 1;
    }
    return -1;
});
Run Code Online (Sandbox Code Playgroud)