АutoСоlumnList — jQuery-плагин для разделения списков на колонки

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

Самый лучший плагин такого типа это, пожалуй, Columnizer. Он предназначен, прежде всего, для разделения контента на колонки. То есть, основным приоритетом в нем является равная высота содержимого. А вот со списками у него получается намного хуже: зачастую данные размещены неравномерно, иногда появляются пустые колонки.

С другими плагинами совсем не сложилось, все они были намного хуже. В общем, написал свой, о чем сейчас и расскажу.

Основная идея: колонки должны быть примерно равные по высоте, т.е. во всех колонках (возможно, кроме последней) должно быть равное количество элементов.

Разметка простая, самое важное — это список:

Далее, в разделе head страницы нужно подключить стили и скрипты:

И ниже вызов обработчика с параметрами:

Плагин принимает 3 параметра:

  • columns — количество колонок, на которое нужно разделить список
  • classname — класс, который нужно присвоить колонке, возможно указать несколько классов через пробел
  • min — минимальное количество элементов в столбце

Если не указывать никаких параметров, то по-умолчанию количество колонок 4, класс — column, min — 1.

Все оформление через стили, так что какими будут списки зависит только от ваших потребностей. Плагин одинаково работает как с OL, так и с UL списками. Тестировался в IE6+ и современных версиях Firefox, Opera, Chrome. Думаю, что и в других версиях проблем быть не должно.

Учитывайте тот факт, что браузеры по-разному обрабатывают нумерованные списки. Например, IE и Opera разделяют нумерацию для каждой колонки, а Firefox и Chrome ведут общую для всего списка.

Changelog

  • 26/02/2017 — Версия 1.2.0 — Добавлена поддержка data-параметров, поддержка gulpjs, небольшие исправления.
  • 25/07/2014 — Проект перенесен на GitHub.
  • 29/03/2011 — Версия 1.0.2 Небольшая оптимизация кода, добавлена поддержка нескольких селекторов, для последней колонки добавляется класс last. Спасибо Михаилу Кобзареву за помощь в разработке.
  • 28/01/2011 — Версия 1.0.1 Добавлена опция для задания минимального количества элементов в колонке. По-умолчанию, один элемент. Например:
  • 05/01/2011 — Вышла версия 1.0

Смотрите ДЕМО или скачайте архив на GitHub.

Буду рад узнать ваше мнение и критику.

  • дарья

    добрый день! все здорово работает, но что, если нужно разбить на колонки список, являющийся вложением, причем третьего уровня (в другие списки), например, в меню? пыталась и так и эдак, ничего не выходит.
    вот пример в исходном виде:
    http://pingmygod.narod.ru/menuTest.html
    пункт «Статьи и переводы» —> Ностальгия обелисков —> и дальше.
    Спасибо!

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

      • дарья

        эх! как жаль. а так чудно работает в принципе. спасибо!

        • Максим

          Если заменить: var els = $(this).find(‘li’);
          на: var els = $(» > ul > li», this);
          то будет вроде то, что вы хотите.

          Если this это # вышестоящего li

          То есть раскладываться на колонки будет только один уровень, без следующих дочерних уровней.

          PS: Спасибо за скрипт, очень помог!

          • дарья

            спасибо! а я в тот же вечер нашла такое решение (возможно, неправильное, я полный ноль пока тут): div class заменить на ul class. По крайней мере, у меня сработало отлично и кроссплатформенно/кроссбраузерно:)

  • OlMa

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

    $(‘ul.topnav>li>div.sub>ul’).each(function(n,element) {
    $(element).autocolumnlist()
    });

    То есть, для каждого вложенного подменю (sub) навигации (topnav) я применяла функцию autocolumnlist().

  • Доработал ваш скрипт, добавив в опции margin, width и самое главное return this.each(function() {, чтобы использовать плагин с несколькими селекторами, например $('ul.one, ul.two').autocolumnlist()

    • Приятно, что скрипт востребован. А зачем margin и width? Лучше оформление выносить в css.

      • Я сам сторонник разделения логики и представления данных, но в данном случае пошел на поводу у товарища, который ни черта не соображает в HTML/CSS/JS, влепив все в один файл для простоты подключения. Он тупо не смог разобраться в движке с кэшированием и нашел только место, куда можно подключить JavaScript-файл.

        Обновите скрипт для применения к нескольким селекторам:

        return this.each(function() {}

      • Вынес определение размерности в переменную для увеличения быстродействия:

        var dimension = els.size();

        так как данная строка в коде встречается более одного раза.

        • Скиньте мне скрипт на почту neolot@gmail.com
          Я посмотрю и выложу с ссылкой на вас.

  • Есть предложение использовать пользовательские атрибуты для внесения в них конфигурации, например:
    [code]
    <ul data-min="4" data-columns="4" data-class="youclass" class="autocolumnlist">…</ul>
    [/code]

    • Neolot

      А в чем разница? Только замусорится html-код, да и не валидно будет.

      • По новой спецификации код будет валидным! Если брать обратную совместимость, то вместо этих атрибутов можно использовать rel, перечислив в нем параметры через запятую, например.

        Представьте ситуацию, когда вы не можете править JS-код сайта. Вы — редактор. И на одной из страниц вам нужно разместить 2 списка: один в 2 колонки, другой — в 3. Человеку будет достаточно прописать атрибуты для тега и все.

        Если вы не против, я немного допилю код, а заодно изменю врапер на ins вместо div, чтобы избавиться от float: left; в пользу display: inline-block;

  • Во что увидел. Очень похоже

    http://www.madeincima.it/download/samples/jquery/easyListSplitter/

  • Дмитрий

    Спасибо большое! Очень пригодилось!

  • Евгений

    НУ блин, опять через id? Почему не классы? Все плагины через классы работают парень!!!!

    • Уважаемый, если вы ничего не понимаете в JQuery, то пишите больше восклицательных знаков.
      Плагину нужно указать селектор, любой. Это может быть как id, так и класс, и даже тупо ul.

  • oldy1111

    Возникает проблема например когда нужно получить 3 колонки, а элементов в списке 4. Получается 2 колонки с 2 элементами, а нужно 1 с 2ми и 2 по одному элементу

  • Коллега , плагин замечательный , я бы посоветовал в коде исправить строку
    var els = $(this).find(‘li’); на var els = $(this).find(‘> li’); тогда работает корректно только с выбранным ul и не трогает вложенные ul (типа если список в списке)

    • Neolot

      Добавил ваше изменение

  • Pavel Kolosov

    Плагин хорош, только мне нужно было округление в другую сторону, добавил параметр, и все замечательно, можешь добавить себе такой функционал вдруг кому понадобится

  • Yuriy Pokhylko

    Добавил поддержку data-параметров. Всего-то 6 лет прошло))

  • Сергей Воронков

    хороший плагин — единственное не хватало деактивации плагина (например при ресайзе). накидал такую функцию:

    $.fn.autocolumnunset = function(params){
    var options = $.extend({}, defaults, params);
    $(this).find(‘div.’+options.classname).replaceWith(function(){
    return $(this).html();
    });
    };