Javascript, чтобы превратить неупорядоченный список в несколько столбцов

Кажется, что это не так просто (хорошо поддерживается) css. Я ищу решение javascript, желательно jQuery.

У меня есть неупорядоченный список:

<ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>        
    ...etc
</ul>

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

A     E
B     F
C
D

Ответ 1

Решение Doug приятно, если вы хотите разбить список на подкатегории.

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

В основном это отображается как сетка. Я использую это для выпадающих меню, чтобы он работал хорошо. Избегайте использования этого, если для каждого элемента списка требуется динамическая высота. Переменная col_height может быть установлена ​​на высоту самого большого элемента, чтобы сделать код более универсальным.

var col_max_height = 6; //Max Items per column
var col_width = 200; //Pixels
var col_height = 33; //Pixels
$('.header ul li ul').each(function() {
    $(this).find('li').each(function(index){
        column = parseInt(index/col_max_height);
        $(this).css('margin-left', column * col_width + 'px')
        if(column > 0) {
            $(this).css('margin-top', (index - (col_max_height * column)  + 1) * -col_height + 'px').addClass('col_'+column);
        }
    });
});

Ответ 2

Вы хотите использовать комбинацию CSS и jQuery, но в теории это очень просто. Выполните полный единый список в HTML, а затем предоставите оболочку через jQuery и разделите список по желанию. Следующая функция делает именно это. Обязательно используйте более специфичный селектор, чем просто ul, когда на самом деле используете script. А id был бы идеальным.

Просмотрите демо здесь

jQuery(function ($) {
  var size = 4,
      $ul  = $("ul"),
      $lis = $ul.children().filter(':gt(' + (size - 1) + ')'),
      loop = Math.ceil($lis.length / size),
      i    = 0;

  $ul.css('float', 'left').wrap("<div style='overflow: hidden'></div>");

  for (; i < loop; i = i + 1) {
    $ul = $("<ul />").css('float', 'left').append($lis.slice(i * size, (i * size) + size)).insertAfter($ul);
  }
});

Ответ 3

См. статью:

Один из второстепенных святых граалей XHTML и CSS - создать единый, семантически логический упорядоченный список, который обертывается в вертикальные столбцы.

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

http://www.alistapart.com/articles/multicolumnlists/

"Лучшее" решение субъективно, но я бы склонялся к произвольным классам.

Ответ 4

@Keyo, спасибо за ваш полезный ответ.

Просто несколько модификаций, необходимых для того, чтобы он работал на моем конце.
(Формула была изменена, возможно, это могло помочь кому-то)

var col_max_item = 2; //Max Items per column
var col_width = $('.header ul li').css('width').replace("px", "");  //Pixels, get width from CSS
var col_height = $('.header ul li').css('height').replace("px", ""); //Pixels, get height from CSS  

    $('.header ul').each(function() { 
        $(this).find('li').each(function(index){ 
            column = parseInt(index/col_max_item);
            $(this).css('margin-left', column * col_width + 'px')
            if(column > 0 && (index / col_max_item) == column) {
                $(this).css('margin-top', (col_max_item * col_height * -1)  + 'px').addClass('col_'+column);
            }
        });
    });

Ответ 6

Просто немного отличается от следующего столбца вместо следующего.

var col_max_height = 6; //Max Items per column
var col_width = 120; //Pixels
var prevCol = 0; 
$('.header ul').each(function() {
    $(this).find('li').each(function(index){
    column = parseInt(index/col_max_height);
    $(this).css('margin-left', column * col_width + 'px')
        if(prevCol != column) {
            $(this).css('margin-top',  '-92px').addClass('col_'+column);
            prevCol = column;
        } else {
            $(this).css('margin-top',  '0px').addClass('col_'+column);
        }
    });
});

Ответ 7

Вы можете сделать это очень легко с помощью jQuery-Columns Plugin, например, чтобы разделить ul с классом .mylist, вы бы сделали

$('.mylist').cols(2);

Здесь живой пример на jsfiddle