Сортировка массива DOM-узлов сверху вниз - PullRequest
2 голосов
/ 09 февраля 2012

У меня есть массив (массив javascript, а не объект jQuery) узлов DOM, который действует как очередь для функции, которая у меня есть, которая их обрабатывает. Этот массив может потенциально содержать элементы, имеющие отношения родитель / потомок, дедушка / потомок и т. Д. Я всегда хочу, чтобы элементы более высокого уровня обрабатывались первыми. Моим первым стремлением было создать функцию быстрой сортировки в javascript, но я знал, что было бы быстрее, если бы я мог использовать нативный метод javascript Array.prototype.sort.

Я пробовал это так:

domElements.sort(function (a, b) {
  return $(a).find(b).length ? 1 :
         $(b).find(a).length ? -1 :
         0;
});

Но, похоже, он не сортировался идеально. У меня все равно иногда были бы дочерние элементы перед их родителями. Почему это не работает? Есть ли способ сделать это с нативной сортировкой javascript?

ОБНОВЛЕНИЕ : Изучив методы ответов, я хотел узнать, как они работают. Здесь - результаты. Не стесняйтесь настроить и посмотреть, как производительность для вас.

Ответы [ 4 ]

2 голосов
/ 09 февраля 2012

Вы можете сэкономить время, используя метод jQuery unique: http://api.jquery.com/jQuery.unique/

jQuery.unique(domElements);
1 голос
/ 09 февраля 2012

(Так как вы попросили меня опубликовать его. :-))

Вы сказали, что хотите, чтобы родительские элементы были дочерними в массиве, но ваш код

domElements.sort(function (a, b) {
  return $(a).find(b).length ? 1 :
         $(b).find(a).length ? -1 :
         0;
});

... возвращает 1, если a является родителем b, что приведет к a позже в массиве, чем b.

Итак, я думаю:

domElements.sort(function (a, b) {
  return $(a).find(b).length ? -1 :
         $(b).find(a).length ? 1 :
         0;
});

Но проверить, является ли элемент потомком другого элемента, так просто, интересно, действительно ли вам нужен allocate-a-jQuery-object-and-then-call-find:

domElements.sort(function (a, b) {
  return isParentOf(a, b) ? -1 :
         isParentOf(b, a) ? 1 :
         0;
});

function isParentOf(parent, elm) {
    while (elm) {
        elm = elm.parentNode;
        if (elm === parent) {
            return true;
        }
    }
    return false;
}

Рабочий пример Но обратите внимание Ответ Тиммивиля & mdash; даже если он выполняет небольшую ненужную работу (приводя в порядок братьев и сестер, когда все, что вам нужно, это родитель / ребенок), для этого есть предварительно запеченная функция jQuery!

0 голосов
/ 09 февраля 2012

Сортировка случайных элементов в документе в соответствии с порядком их исходного кода держите дочерние узлы и братьев и сестер в правильном положении.

if(!Array.prototype.indexOf){
    Array.prototype.indexOf= function(what, i){
        if(typeof i!= 'number') i= 0;
        var L= this.length;
        while(i< L){
            if(this[i]=== what) return i;
            ++i;
        }
        return -1;
    }
}
function nodeSort(nodesArray, pa){
    pa= pa || document;
    var original= [], src= pa.getElementsByTagName('*'), L= src.length;
    for(var i= 0; i<L; i++){
        if(nodesArray.indexOf(src[i])!=-1) original.push(src[i]);
    }
    return nodesArray.sort(function(a, b){
        return original.indexOf(a)- original.indexOf(b);
    });
}
0 голосов
/ 09 февраля 2012

Похоже, я перепутал отрицательный знак на одном:

domElements.sort(function (a, b) {
  return $(a).find(b).length ? -1 :
         $(b).find(a).length ? 1 :
         0;
});

Кажется, работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...