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

问题描述:

我已经构造了一个当前正在使用的jQuery插件,该插件可以让我将DOM元素存储在数组中,主要是因为能够在这些元素旁边存储更多信息,而不必使用not-so-快速 data().

I've structured a jQuery plugin I'm currently working on in a way that has me storing DOM elements in an array, mostly for being able to store more information next to these elements without having to use the not-so-fast data().

该数组看起来像:

[
    { element: DOMElement3, additionalData1: …, additionalData2: … },
    { element: DOMElement1, additionalData1: …, additionalData2: … },
    { element: DOMElement2, additionalData1: …, additionalData2: … },
]

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

The way this plugin works prevents me from pushing these elements to the array in a predictable order, which means DOMElement3 can in fact find itself at an index lower than DOMElement2's.

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

However, I need these array elements to be sorted in the same order as the DOM elements they contain appear in the DOM. The previous example array, once sorted, would look like this:

[
    { element: DOMElement1, additionalData1: …, additionalData2: … },
    { element: DOMElement2, additionalData1: …, additionalData2: … },
    { element: DOMElement3, additionalData1: …, additionalData2: … },
]

这当然是如果 DOMElement1 出现在DOM中的 DOMElement2 之前,并且 DOMElement2 出现在 DOMElement3 之前

This is, of course, if DOMElement1 appears before DOMElement2 in the DOM, and DOMElement2 before DOMElement3.

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

The jQuery add() method returns a set of DOM elements in the same order as they appear in the DOM. I could be using this, but the requirement is that I work with a jQuery collection – which means I'd have to refactor a huge chunk of the abovementioned plugin to use a different storage format. That's why I consider this a last-resort solution.

我会想到 map() 和绑定到每个DOM元素的某种全局DOM索引可以解决问题,但似乎没有这样的全局DOM索引".

I would have imagined that map() and a sort of global DOM index tied to each DOM element would have done the trick, but there doesn't appear to be such a "global DOM index".

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

What approach can you think of? (If writing code, both vanilla JS and jQuery are welcome.)

有一个非常有用的函数,称为

There is a very useful function called compareDocumentPosition, which returns a number based on where two elements are relative to each other. You can use this in a .sort callback:

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;
});