Подтвердить что ты не робот

Самый простой способ сортировки узлов DOM?

Если у меня есть список вроде этого:

<ul id="mylist">
    <li id="list-item1">text 1</li>
    <li id="list-item2">text 2</li>
    <li id="list-item3">text 3</li>
    <li id="list-item4">text 4</li>
</ul>

Какой самый простой способ перенастроить узлы DOM по моим предпочтениям? (Это должно произойти автоматически при загрузке страницы, предпочтение в порядке списка получается из файла cookie)

например.

<ul id="mylist">
    <li id="list-item3">text 3</li>
    <li id="list-item4">text 4</li>
    <li id="list-item2">text 2</li>
    <li id="list-item1">text 1</li>
</ul>
4b9b3361

Ответ 1

Хотя, возможно, более простой способ сделать это с помощью библиотеки JS, здесь работает решение с использованием vanilla js.

var list = document.getElementById('mylist');

var items = list.childNodes;
var itemsArr = [];
for (var i in items) {
    if (items[i].nodeType == 1) { // get rid of the whitespace text nodes
        itemsArr.push(items[i]);
    }
}

itemsArr.sort(function(a, b) {
  return a.innerHTML == b.innerHTML
          ? 0
          : (a.innerHTML > b.innerHTML ? 1 : -1);
});

for (i = 0; i < itemsArr.length; ++i) {
  list.appendChild(itemsArr[i]);
}

Ответ 2

Возможно, вы обнаружите, что сортировка узлов DOM не работает хорошо. Другой подход заключался бы в том, чтобы в вашем javascript был массив, представляющий данные, которые будут попадать в узлы DOM, сортировать эти данные и затем восстанавливать div, который содержит узлы DOM.

Может быть, у вас не так много узлов для сортировки, так что это не имеет значения. Мой опыт основан на попытке сортировать таблицы HTML, манипулируя DOM, включая таблицы с сотнями строк и несколько десятков столбцов.

Ответ 3

Смотрите в действии: http://jsfiddle.net/stefek99/y7JyT/

    jQuery.fn.sortDomElements = (function() {
        return function(comparator) {
            return Array.prototype.sort.call(this, comparator).each(function(i) {
                  this.parentNode.appendChild(this);
            });
        };
    })();

Terse

Ответ 4

Если вы уже используете jQuery, я бы рекомендовал tinysort: http://tinysort.sjeiti.com/

$("li").tsort({order:"asc"});
$("li").tsort({order:"desc"});

Ответ 5

Моя версия, надеюсь, будет полезна для других:

var p = document.getElementById('mylist');
Array.prototype.slice.call(p.children)
  .map(function (x) { return p.removeChild(x); })
  .sort(function (x, y) { return /* sort logic */; })
  .forEach(function (x) { p.appendChild(x); });

Ответ 6

Здесь функция ES6 для сортировки узлов DOM:

const sortChildren = ({ container, childSelector, getScore }) => {
  const items = [...container.querySelectorAll(childSelector)];

  items
    .sort((a, b) => getScore(b) - getScore(a))
    .forEach(item => container.appendChild(item));
};

Вот как вы могли бы использовать его для сортировки Нераспределенные отзывы пользователей по счету:

sortChildren({
  container: document.querySelector("#main-stream"),
  childSelector: ".item",
  getScore: item => {
    const rating = item.querySelector(".rating");
    if (!rating) return 0;
    const scoreString = [...rating.classList].find(c => /r\d+/.test(c));
    const score = parseInt(scoreString.slice(1));
    return score;
  }
});

Ответ 7

не анализируя слишком много, если это приносит что-то новое в таблицу, я обычно использую это:

function forEach(ar, func){ if(ar){for(var i=ar.length; i--; ){ func(ar[i], i); }} }
function removeElement(node){ return node.parentNode.removeChild(node); }
function insertBefore(ref){ return function(node){ return ref.parentNode.insertBefore(node, ref); }; }

function sort(items, greater){ 
    var marker = insertBefore(items[0])(document.createElement("div")); //in case there is stuff before/after the sortees
    forEach(items, removeElement);
    items.sort(greater); 
    items.reverse(); //because the last will be first when reappending
    forEach(items, insertBefore(marker));
    removeElement(marker);
} 

где item - массив дочерних элементов одного и того же родителя. мы удаляем начало с последнего и добавляем начало с первого, чтобы избежать мерцания в верхней части, которая, вероятно, находится на экране. Я обычно получаю свой массив элементов следующим образом:

forEachSnapshot(document.evaluate(..., 6, null), function(n, i){ items[i] = n; });

Ответ 8

Используйте синтаксис es6 для детей-курортов:

var list = $('#test-list')[0]
var arr =[];
for(let i=0;i<list.children.length;i++){
    arr.push(list.children[i])
}


arr.sort((a,b)=>a.innerText>b.innerText)
arr.map(node=>list.appendChild(node))