Статья о сортировке HTML-таблиц была написана год назад. Так получилось, что описываемая технология заинтересовала некоторых начинающих программистов, и они стали задавать вопросы и высказывать пожелания. В результате к своему юбилею скрипт изменился до неузнаваемости: первоначальное торжественное заявление о 150-ти строках утратило силу, так как строк стало почти вдвое больше (файл tabsort1.3.js). Но главное, совершенно изменилась его сущность. Настолько, что описывать его надо заново (потому что уже и сам автор мало что стал в нём понимать).
Чтобы сортировать строки любой HTML-таблицы без перезагрузки страницы с помощью скрипта tabsort1.3.js, нужно выполнить минимум два действия:
Для большей наглядности и удобства пользования нужно также присоединить к таблице файл стилей tabsort.css: <link rel='stylesheet' href='static/tabsort.css' ... – будут подсвечиваться строки таблицы и будет меняться форма курсора при наведении мыши на заголовок таблицы.
Использование достаточно просто: для сортировки таблицы нужно щелкнуть по заголовку выбранного столбца. Если при щелчке удерживать клавишу Shift, ячейки столбца будут сортироваться как числа (по умолчанию – как строки).
Тип сортировки нужно назначать в HTML-коде самой таблицы – с помощью атрибута axis в ячейке заголовка:
В заголовке таблицы может быть несколько строк. Сортировщик может правильно обрабатывать такую структуру, если поместить строки заголовка в элемент thead (между тэгами <thead> и </thead>).
Пожелания по работе скрипта были разные, и не всегда очевидно полезные, поэтому часть возможностей управляется теперь с помощью секции «Настройки» в начале кода в файле скрипта tabsort1.3.js. Настройки эти следующие:
Вначале всё было хорошо: пользователь для сортировки щёлкает по ячейке таблицы – следовательно нужна функция, которая срабатывает по событию onclick – clickTab() (1). Для сортировки такого сложного объекта, как таблица требуется ещё одна функция (которая, собственно, и производит сортировку) – cmpRow() (2). Ну, и нужно проверить, есть ли на странице таблицы, пригодные для сортировки (с класснэйм sortable), что делает функция prepTabs() (3). Так было в первой версии Сортировщика – три функции и 150 строк (с комментариями).
Первое осложнение вызвала система сохранения сортировки: функцию сортировки понадобилось вызывать не только по событию onclick, но и по событию «загрузка страницы» (если установлена опция use_cookie). Так появилась четвёртая функция – sortTab() (4), выделенная в отдельное прозводство из clickTab(). Ну, и, соответственно, потянулись глобальные переменные настроек: use_cookie, use_title... Дальше – больше. Закончилось так:
1. Страница открывается, функция prepTabs():
2. Пользователь щёлкает по ячейке заголовка, функция clickTab():
3. Функция sortTab():
Есть ещё несколько мелких функций, назначение которых более-менее очевидно. Интереснее другое: как повысить скорость работы Сортировщика? Поиск в сети приводит к статьям, описывающим различные алгоритмы самой функции сортировки. Встроенная в Javascript функция – sort(). Но люди пишут о том, что придумали более быстрые функции. Дальше другие люди активно обсуждают выигрыш в миллисекундах, даваемый тем или иным хитрым методом (Хоара, «истинный» n log n и проч.), и на этом всё заканчивается.
На практике же основную проблему сортировки представляют не расчёты, а прорисовка HTML-элементов (работа с DOM): голые расчёты (сортировка массива) в общем случае занимают в десятки раз меньше времени, чем создание массива из элементов HTML и отображение отсортированного массива обратно на страницу. В разных браузерах, конечно, по-разному. Больше всех традиционно тормозит с DOM Firefox (ФФ), с расчётами – Интернет Эксплорер (ИЕ). В ИЕ8 скорость расчётов существенно увеличилась, но природу не обманешь (если программа из ГовноСофта, это всё равно где-нибудь вылезет): теперь в ИЕ скорость работы с DOM стала значительно хуже.
На чём и где можно сэкономить время «реальной» сортировки таблицы?
Тестировалась таблица в 1000 строк: limit1001.htm.
На медленном компьютере в Опере 9.50 браузер не успевает... ну, короче, обманывает себя и людей: Опера, как всегда, поспешно сообщает, что всё уже загрузилось, и сама начинает в это верить – и запускает Javascript, а у ячейки ЕЩЁ НЕТ свойства cellIndex (во дают)! Баг обходится таким же тупым способом (против лома...): вызывается alert, и пока пользователь думает и нажимает кнопку, подгружаются недостающие куски DOM'а.
На быстром компьютере ИЕ8 с использованием appendChild (вместо innerHTML) почему-то сортирует (вернее, рисует) большую таблицу в течение 220000 мс (то есть несколько минут). Хотя ИЕ6 на медленном компьютере работает вполне предсказуемо. Продублировал проверку на таблице в 200 строк – 6 секунд. Видимо, последние могзи говно микрософтеров ушли на повышение скорости расчётов Javascript, а научить свой говнобраузер рисовать DOM уже ума не хватило.
Safari и Google Chrom показывают просто чудовищную скорость сортировки и отображения большой таблицы, причём, независимо от метода отображения (appendChild или innerHTML).
Ну, современные Опера и ФФ, как всегда, где-то посередине (Опера прикидывается в разы быстрее, но врёт, конечно, зараза).
Лучше всего, наверное, проверять скорость на таблице в 200 строк: limit200.htm. Совсем маленький файл демонстрирует разные заголовки таблиц – thead2.htm. Скрипт tabsort1.3.js можно скачать и использовать, с ним вместе нужен также файл ir2.js, в котором хранятся некоторые нужные для работы функции (типа addLoadEvent, addClass, deselect...).
А не подскажите каким условием можно задать автоматическую сортировку таблицы по ID от большего к меньшем.
Здравствуйте. Можно ли заставить скрипт сортировать таблицу по заданному столбцу ПРИ ЗАГРУЗКЕ СТРАНИЦЫ? Не нашел что-то где об этом написано (может плохо искал).
Здравствуйте, Алекс! Теоретически всё возможно. Система развёрнутых визуальных настроек описана в статье tabsort004.aspx (рабочий пример см. на стр.: http://ir2.ru/static/sort0.03/table404.htm).
Проблема «утечки мозгов» при работе Сортировщика в ИЕ локализована: фатальный тормоз возникает при использовании «зебры» (раскрашивании строк таблицы в чередующиеся цвета). Причём, раньше всё более-менее работало, а соломинка, переломившая спину Осла, вот откуда: MrTopa справедливо указал на неточность раскраски и предложил вполне разумное решение – удалять предыдущий цвет перед добавлением нового (после сортировки). Так вот, это лишнее действие (удаление предыдущего класснейма) и оказалось для ИЕ фатальным.
Решение – убрать «зебру». Точнее, оставить это на усмотрение веб-мастера: в секцию «Настройки» добавляется параметр use_zebra и предупреждение о том, что назначение true этому параметру вместе с предыдущим (use_appendChild) может подвесить ИЕ.
Да, и такое решение всё меняет: теперь (без зебры) ИЕ6 сортирует таблицу в 4 раза быстрее с включённым use_appendChild (=true).
upd 15:19 02.10.2010
Ещё иллюзия. В ИЕ вроде бы можно управлять CSS с помощью каких-то там «behavior» и «expression». Поскольку я довольно смутно представляю, что это и как, обратился с вопросом к ПС, и, ткнув в первую попавшую ссылку (http://www.lysenka.net/web/6/, Andrei Lysenka), нашёл и протестировал решение. Всё равно в большой таблице (limit1001.htm) получилась жопа, но вы можете попробовать сами (доверять нельзя никому), добавив в начало файла tabsort1.3.js следующий код:
Никто ничего не пишет, значит, настало время заняться стрелками (когда коту делать нечего). С самого начала было ясно, что стрелки делать придётся, просто не было повода. Хотел делать как обычно – картинкой (треугольничком), но при анализе скрипта конкурента (http://debugger.ru/blog/bystraja_sortirovka_tablic) обнаружил стрелки-треугольнички и заинтересовался, как они сделаны. Начал искать символы, что-то вроде ■, а их нет. Идея оказалась гениально простой – треугольники сделаны из border!
Действительно, можно было бы и самому догадаться. Ведь что такое border? Это четыре доски по краям прямоугольника. Как доски могут крепиться друг к другу? Если концы прямоугольные, неизбежно возникнет вопрос, какая [доска] главнее – правая или нижняя (что в W3C недопустимо). Поэтому в местах скрепления доски режут под углом 45 градусов. Такая конструкция содержит в себе форму треугольника, которую вполне можно извлечь, правильно обработав напильником.
Пришлось позаимствовать идею практически полностью. В благодарность помещаю на сайт таблицу, работающую на SortTable.1.5.1 (для сравнения с собственными примерами): sorttable.htm. Ну, а вот и мои примеры со скриптом tabsort1.4.js: thead3.htm, limit201.htm, limit1002.htm (1000 строк). В версии 1.4 кроме добавленных стрелок изменилось следующее: используется только один файл tabsort1.4.js (библиотека ir2.js не нужна). Ну, и повысилась необходимость файла стилей tabsort.css (раздел «arrows»).
Более правильная версия сейчас постоянно находится по адресу tabsort2.1.js. Трудно (и всё меньше понятно, зачем) синхронизировать с tabsort1.4, поэтому tabsort1.4.js больше, видимо, не будет поддерживаться. Скрипт сортировки дорабатывается теперь только вместе с фильтрацией данных.
Тестовые таблицы: limit202.htm, thead4.htm, limit1003.htm. Сравнение с jquery.tablesorter.js в двух файлах на базе списка торрентов: test-tracker/tracker.php.htm (jquery.tablesorter.js) и test-tracker/tracker2.php.htm (tabsort2.1.js - наш, о котором речь в статье).
test-tracker/tracker3.php.htm - испытание ещё одного сортировщика, самого маленького в мире и очень классного во многих отношениях (http://www.leigeber.com/2009/11/advanced-javascript-table-sorter/)
Ну, и проверка работы на таблице в 3000 строк: test-tracker/limit3000.htm