Ну, это заняло намного больше времени, чем я ожидал (мне пришлось научиться писать плагин), но я наконец собрал что-то, что делает то, что вы хотите. С небольшой оговоркой, но мы вернемся к этому позже.
На jsbin есть живая демонстрация, показывающая список, который вы опубликовали, пройдя его через плагин, я дал ему минимальный стиль, но не очень. Очевидно, что вы также можете отредактировать его, если вы нажмете кнопку «Редактировать с помощью JS Bin».
JQuery - все ниже, так же как и варианты, которые он может принять (в настоящее время):
Сам плагин:
Плагин отредактирован (заменен более поздним воплощением, опубликованным ниже).
Как это можно назвать (как в демоверсии jsbin):
$(document).ready(
function() {
$('#container').wrapSubs({
rows: 2
});
}
);
Вызов его, как указано выше, преобразует ваш собственный список (хотя и с id
из «контейнера»):
<ul id="container">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
</ul>
На следующее:
<ul id="container">
<li id="column_1">
<ul>
<li>1</li>
<li>2</li>
</ul>
</li>
<li id="column_2">
<ul>
<li>3</li>
<li>4</li>
</ul>
</li>
<li id="column_3">
<ul>
<li>5</li>
<li>6</li>
</ul>
</li>
<li id="column_4">
<ul>
<li>7</li>
<li>8</li>
</ul>
</li>
<li id="column_5">
<ul>
<li>9</li>
<li>10</li>
</ul>
</li>
<li id="column_5">
<ul>
<li>11</li>
<li>12</li>
</ul>
</li>
</ul>
Другие баллы:
Он может быть вызван для любого элемента, который содержит дочерние элементы, я не проверил его всесторонне с каноном доступных HTML-элементов, но я убедился, что он работает с:
- дивы,
- изображения
- пролеты,
- списки (кроме
dl
).
Кажется, он довольно успешно поддерживает цепочку, хотя я не приложил усилий, чтобы она работала с обратными вызовами. Главным образом потому, что я только научился писать плагины за последние четыре часа или около того.
Он не выполняет никакой проверки, поэтому мусор вернет вас обратно. Или, вернее, очень много ошибок проверки HTML, но он точно соберет HTML, с которым вы работаете. По умолчанию используется допущение, что он будет работать со списками, но это можно изменить (связанный JS Bin показывает, что он вызывается в абзацах и вкладывает их в blockquote
s и div
s.
Я не знаю, что еще сказать, кроме «вот, пожалуйста». =)
Есть вопросы, оставляйте комментарии. В противном случае, есть только одна оговорка (единственная, о которой я могу подумать, но может быть и больше), ниже.
<ч />
Оговорка:
Поскольку я решил работать над массивом в обратном направлении (чтобы избежать путаницы с такими вещами, как индексы на ранних этапах), вы обнаружите, что иногда все столбцы, кроме первого, имеют «правильное» количество элементов вместо последнего.
Очевидно, что я с радостью сообщаю об этом тем, кто захочет поиграть с ним и сделать его лучше (это работает, и я до смешного горжусь собой за то, что написал это, но он все еще может использовать улучшения и полировку), если они мне нравится.
<ч />
Отредактировано , чтобы включить слегка переработанную версию плагина:
(function($) {
$.fn.wrapSubs = function(options) {
options = $.extend($.fn.wrapSubs.defaults,options);
// External vars, defaults or from user:
var rows = options.rows; // number of 'rows' in each column
var wrapper = options.wrapper; // the item in which 'objects' are wrapped
var columns = options.columns; // the container of the wrapper
var idPrefix = options.idPrefix; // the generated columns' id
var orientation = options.orientation;
var autofit = options.autofit;
var thisId = $(this).attr('id');
// Internal vars, from plug-in itself:
var numX = $(this).children().length;
var cols = Math.ceil(numX/rows);
var lastX = $(this).find(':last-child').index();
if (orientation == 'vertical') {
var colsOrRows = 'col';
var cellOrientation = 'row';
}
else if (orientation == 'horizontal') {
var colsOrRows = 'row';
var cellOrientation = 'col';
}
// Sanity checks
if (rows > numX) {
rows = numX;
}
for (i=cols; i>0; i--) {
$(document.createElement(columns))
.attr('id',idPrefix+i)
.addClass(orientation)
.prependTo($(this));
$(document.createElement(wrapper))
.appendTo($('#'+ idPrefix +i));
for (c=rows; c>0; c--) {
if (numX > 0) {
$(this).find(':last').addClass(cellOrientation)
.prependTo($('#'+ idPrefix +i+'>' + wrapper));
numX--;
}
}
}
if (autofit && orientation == 'vertical') {
var numCols = $('#'+thisId).find('.vertical').length;
var colWidth = Math.floor($('#'+thisId).width()/numCols);
$('.vertical').css('width',colWidth + 'px');
}
else if (autofit && orientation == 'horizontal') {
var numCols = $('#'+thisId+'> .horizontal:last').find('.col').length;
var colWidth = Math.floor($('#'+thisId).width()/numCols);
$('.horizontal').find(columns).css({
'width':colWidth,
'margin': 0
}).parent().css({
'margin':0,
'width': '100%'});
console.log(numCols);
}
return this;
}
$.fn.wrapSubs.defaults = {
rows: 3,
wrapper: 'ul',
columns: 'li',
idPrefix: 'column_',
orientation: 'vertical',
autofit: false
};
})(jQuery);
Эта версия может сделать немного больше, чем предыдущая (теперь отредактированная) версия:
- 'rows' - это, по сути, количество элементов, которые вы хотите сгруппировать вместе.
- 'wrapper' - это контейнер, в который нужно сгруппировать каждую группу.
- 'columns' - это оболочка для 'wrapper' (по умолчанию она предназначена для обработки
ul
, и ul
не может быть прямым потомком другого ul
).
- 'idPrefix' означает, что этот плагин можно вызывать для нескольких элементов на одной странице (также см. Пункт 7).
- 'ориентация' означает, что классы будут иметь разумное название.
6 'autofit', если autofit равно
true
, то скрипт автоматически подгонит «строки» по ширине их родительского элемента.
- скрипт теперь использует объект
$(this)
повсюду, а не предполагает, что элемент, к которому он применяется, называется #container
.