Comments 17
Если бы вы пользовались jQuery, то есть неплохой плагин tablesorter.com/docs/
Но спасибо за реализацию на чистом JS
Но спасибо за реализацию на чистом JS
+1
так же для jQuery есть datatables.net/
0
UFO just landed and posted this here
Сортировка по времени не совсем корректно работает.
gyazo.com/a304e33aaf01ba0eef7ffa97d02d4d43
gyazo.com/a304e33aaf01ba0eef7ffa97d02d4d43
+1
Намного оптимальней будет хранить данные со ссылкой на строку в таблице отдельно от представления, тогда не придется доставать данные из DOM для сортировки.
+1
А можно несколько подробнее?
0
Человек предлагает, один раз создать массив из 100500 данных таблицы, где одно из значений будет ссылкой на DOM элемент таблицы. После сортировки надо будет пробежаться по этим ссылкам и расставить DOM элементы (в данным случае это TR) в порядке сортировки.
Как вариант, чтоб не захламлять память, можно в этом массиве данные заменить цифрами в порядке сортировки.
Пример:
было — ['Брест', 'Абакан', 'Воркута']
стало — [2,1,3]
А потом это уже сортировать легко и быстро.
Как вариант, чтоб не захламлять память, можно в этом массиве данные заменить цифрами в порядке сортировки.
Пример:
было — ['Брест', 'Абакан', 'Воркута']
стало — [2,1,3]
А потом это уже сортировать легко и быстро.
0
Несколько замечаний по коду:
1. TableSort имеет слишком много параметров, смысл которых сразу из вызывающего кода и не разберёшь
Лучше так
2. Много переменных с глобальной областью видимости, хотя по замыслу их область видимости должна ограничиваться функцией TableSort. Как результат, код не будет работать в strict mode.
3. Не создавайте массивы, используя конструктор. Скорей всего Ваши коллеги будут подражать Вам и рано или поздно потратят много эмоций, чтобы понять, что
1. TableSort имеет слишком много параметров, смысл которых сразу из вызывающего кода и не разберёшь
Лучше так
new TableSort({
idTbl: 'idTbl',
defSortCol: 0,
firstRow: 1,
needClasses: ['add', 'edd'],
listClasses: ['odd', '']
});
2. Много переменных с глобальной областью видимости, хотя по замыслу их область видимости должна ограничиваться функцией TableSort. Как результат, код не будет работать в strict mode.
3. Не создавайте массивы, используя конструктор. Скорей всего Ваши коллеги будут подражать Вам и рано или поздно потратят много эмоций, чтобы понять, что
var arr = new Array(10);
и var arr = [10];
— совсем не одно и то же.0
Спасибо что написали плагин.
Таких как вы становится все меньше.
plugindetector.com/category/tables
Tablesorter конечно более надежен и многофункционален.
И вообще поддержка и развитие это очень серьезная задача.
Гораздо более серьезная чем первоначальное написание.
Таких как вы становится все меньше.
plugindetector.com/category/tables
Tablesorter конечно более надежен и многофункционален.
И вообще поддержка и развитие это очень серьезная задача.
Гораздо более серьезная чем первоначальное написание.
-1
Приведенный способ среди всех, которые я видел, является средним (как по быстродействию, так и по сложности реализации). Действительно хорошим советом является отделение данных от DOM (KAdot). Это увеличит скорость.
Как-нибудь напишу статьи про:
1) построение HTML с помощью JS;
2) сортировку данных в таблицах.
Автору плюсик за старание.
Как-нибудь напишу статьи про:
1) построение HTML с помощью JS;
2) сортировку данных в таблицах.
Автору плюсик за старание.
0
Ваше решение, мягко говоря, не оптимально и годится для примера того «как делать не надо».
Обратим внимание на некоторые части вашего решения.
1. Для отделения мух от котлет в таблицах используются секции thead, tbody, tfoot. Если вы вынесете ваш заголовок (строку с th) в thead, вам не нужно будет задавать firstRow. В будущем вы можете добавить еще и tfoot для подвала. Секций tbody может быть несколько и видимо сортировать нужно в каждой секции отдельно (если конечно ваша логика вашего алгоритма не предусматривает иного).
2. Вы делаете очень накладные выборки и не кешируете их. Например:
Этот код будет работать безумно долго, так как для строки вы N^2 раз выбираете все ячейки. То есть браузер перебирает N^2 DOM там где достаточно одного раза. Так же не забываем, что getElementsByTagName возвращает не массив, а коллекцию и обращение к length приводит к вычитыванию размерности этой коллекции. Об этом пишут практически в любом мануале по работе с DOM. Оптимальным (в плане работы с DOM) будет вариант:
3. Вот скажите, зачем вы таскаете html ячеек? Сначала вы нагружаете браузер когда перебираете ячейки, потом когда считываете innerHTML (он вычисляется), потом опять перебираете, и присваиваете html другой ячейке, заставляя браузер парсить этот html, а заканчиваете переносом классов. Почему нельзя перемещать строки?
Вся сортировка сводится к
Вот и все — функции getDataTable, _sort, showSortTable, doStyle можете удалить.
4. Кстати об initSort, она должна принимать номер колонки и функцию нормализации. По данным в html нельзя определить что за тип — это строка, число, дата или еще что. То есть нужно передавать:
5. Этот код не правильно отсортирует если в таблице будут отрицательные числа
6. Вместо добавления изображений в заголовки, лучше добавлять/удалять класс, а стили, в том числе и изображения, задавать через css.
7. Чередующиеся классы не является обязательным атрибутом таблицы, потому можно воспользоваться правилами :nth-child(2n) или :nth-child(2n + 1) чтобы раскрасить таблицу в зебру.
В старых браузерах не будет зебры, но это не фатально, к тому же таких браузеров все меньше с каждым. Зато код будет меньше и чище и лучше стилизоваться через css.
В итоге ваша инициализация сортировки, если применить все рекомендации, будет выглядеть так:
И кода в разы меньше.
Удачи.
Обратим внимание на некоторые части вашего решения.
1. Для отделения мух от котлет в таблицах используются секции thead, tbody, tfoot. Если вы вынесете ваш заголовок (строку с th) в thead, вам не нужно будет задавать firstRow. В будущем вы можете добавить еще и tfoot для подвала. Секций tbody может быть несколько и видимо сортировать нужно в каждой секции отдельно (если конечно ваша логика вашего алгоритма не предусматривает иного).
2. Вы делаете очень накладные выборки и не кешируете их. Например:
for (j=0; j<allTrs[i].getElementsByTagName('td').length; j++) {
tblData[i-numColTr][j] = allTrs[i].getElementsByTagName('td').item(j).innerHTML;
}
Этот код будет работать безумно долго, так как для строки вы N^2 раз выбираете все ячейки. То есть браузер перебирает N^2 DOM там где достаточно одного раза. Так же не забываем, что getElementsByTagName возвращает не массив, а коллекцию и обращение к length приводит к вычитыванию размерности этой коллекции. Об этом пишут практически в любом мануале по работе с DOM. Оптимальным (в плане работы с DOM) будет вариант:
var cells = allTrs[i].getElementsByTagName('td');
for (j = 0, cell; cell = cells[j]; j++) {
tblData[i-numColTr][j] = cell.innerHTML;
}
3. Вот скажите, зачем вы таскаете html ячеек? Сначала вы нагружаете браузер когда перебираете ячейки, потом когда считываете innerHTML (он вычисляется), потом опять перебираете, и присваиваете html другой ячейке, заставляя браузер парсить этот html, а заканчиваете переносом классов. Почему нельзя перемещать строки?
Вся сортировка сводится к
var allTrs = tbl.tBodies[0].getElementsByTagName('tr');
...
this.initSort = function (newCol, normalize) {
if (newCol == curSortCol)
{
curSortUp = !curSortUp;
}
else
{
curSortUp = true;
curSortCol = newCol;
}
// вычисляем значение для сортировки
for (var i = 0, row; row = allTrs[i]; i++)
row.sortValue = normalize(row.childNodes[columnNum].innerHTML);
// сортируем
allTrs.sort(function(a, b){
return (a.sortValue > b.sortValue) || -(a.sortValue < b.sortValue);
});
if (!curSortUp)
allTrs.reverse();
// выставляем ряды в нужном порядке
for (var i = allTrs.length - 1, row, last = null; row = allTrs[i]; i--)
{
row.parentNode.insertBefore(row, last);
// тут можно сделать что-то с чередующимися классами
last = row;
}
Вот и все — функции getDataTable, _sort, showSortTable, doStyle можете удалить.
4. Кстати об initSort, она должна принимать номер колонки и функцию нормализации. По данным в html нельзя определить что за тип — это строка, число, дата или еще что. То есть нужно передавать:
initSort(1, Number); // для числовой сортировки
initSort(1, String); // для строковой
initSort(1, function(value){ return value.toLowerCase() }) // для строковой без учета регистра
initSort(1, function(value){ return +new Date(value) }) // для сортировки дат
// но здесь value должно быть определенного формата, либо же пишется функция разбора даты..
// даты лучше сортировать как числа
// в любом случае вы вольны определить значение для сортировки так как нужно,
// автоматически это сделать не получится
// Типовые сортировки можно сохранить в константы
TableSort.prototype.SORT_DATE = function(value){ return +new Date(value) };
...
table.initSort(1, table.SORT_DATE);
5. Этот код не правильно отсортирует если в таблице будут отрицательные числа
function _sort(a1, b1) {
...
if (parseFloat(a) && parseFloat(b)) {
return parseFloat(a) - parseFloat(b);
...
6. Вместо добавления изображений в заголовки, лучше добавлять/удалять класс, а стили, в том числе и изображения, задавать через css.
7. Чередующиеся классы не является обязательным атрибутом таблицы, потому можно воспользоваться правилами :nth-child(2n) или :nth-child(2n + 1) чтобы раскрасить таблицу в зебру.
tr:nth-child(2n)
{
background: gray;
}
В старых браузерах не будет зебры, но это не фатально, к тому же таких браузеров все меньше с каждым. Зато код будет меньше и чище и лучше стилизоваться через css.
В итоге ваша инициализация сортировки, если применить все рекомендации, будет выглядеть так:
var infoTblSort = new TableSort("idTbl", 0);
И кода в разы меньше.
Удачи.
0
Sign up to leave a comment.
Javascript. Сортировка таблицы