JavaScript/jQuery сортировка элементов DOM
Доброй ночи, коллеги,
столкнулся с задачей сортировки группы элементов DOM для отображения в две или три колонки в зависимости от ширины окна браузера пользователя. В проекте используется Bootstrap. Вот такой простенький HTML отобразит данные в две или три колонки в зависимости от ширины окна браузера (у всех вложенных div-ов есть CSS свойство {float: left}). <div id="list"> <div data-count="7" class="col-xs-6 col-lg-4">07</div> <div data-count="8" class="col-xs-6 col-lg-4">08</div> <div data-count="9" class="col-xs-6 col-lg-4">09</div> <div data-count="10" class="col-xs-6 col-lg-4">10</div> <div data-count="11" class="col-xs-6 col-lg-4">11</div> <div data-count="12" class="col-xs-6 col-lg-4">12</div> <div data-count="1" class="col-xs-6 col-lg-4">01</div> <div data-count="2" class="col-xs-6 col-lg-4">02</div> <div data-count="3" class="col-xs-6 col-lg-4">03</div> <div data-count="4" class="col-xs-6 col-lg-4">04</div> <div data-count="5" class="col-xs-6 col-lg-4">05</div> <div data-count="6" class="col-xs-6 col-lg-4">06</div> <div data-count="13" class="col-xs-6 col-lg-4">13</div> </div> Задача отсортировать элементы так, чтобы "на выходе" вывод в три колонки выглядел так 1 6 11 2 7 12 3 8 13 4 9 5 10 Ну, и в две соответственно так 1 8 2 9 3 10 4 11 5 12 6 13 7 Задача для меня оказалась непосильной, прошу помощи у гуру. Пока что у меня получилось следующее:
function sortList()
{
var data = $("#list > div");
// Сначала сортируем элементы по порядку
// по аттрибуту 'data-count'
data.sort(function (a, b)
{
a = parseInt($(a).attr('data-count'), 10);
b = parseInt($(b).attr('data-count'), 10);
if(a > b)
{
return 1;
}
else if(a < b)
{
return -1;
}
else
{
return 0;
}
});
var result = {};
var cols = 3; // К-во колонок
var rows = Math.ceil($(data).size()/cols);
var prev;
var i = 0;
for(var row = 1; row <= rows; row++)
{
for(var col = 1; col <= cols; col++)
{
var index = (col == 1) ? row : row + (rows * (col - 1));
index--;
if(index in data)
{
result[i] = data[index];
i++;
}
else
{
// Здесь нужно как-то добавить пустой
// элемент <div class="col-xs-6 col-lg-4"></div>
// но как ?????????
// $(result[i-1]).after('<div class="col-xs-6 col-lg-4">-</div>'); НЕ РАБОТАЕТ
}
}
}
$('#list').html(result);
}
Не знаю, насколько данный код оптимален, но он работает, за исключением того, что я не придумал как добавить новый элемент пустышку |
РНР знаете? Есть в нем функция разбивающая массив на части array_chunk(), правда вывод будет не так как у вас, а
1 2 3 4 5 6 7 8 Если пойдет, то js-аналог ее здесь найдете. |
|
onotole,
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
#list{
width:300px;
display:flex;
flex-flow:column wrap;
height:300px;
}
#list>div{
-webkit-animation:spin 5s ease-in-out infinite 2s;
animation:spin 5s ease-in-out infinite 2s;
width:33%;
height:19%;
border:1px #FF0033 solid;
text-align:center;
line-height:2em;
}
@keyframes spin{
50%{
width:50%;
height:12%;
}
100%{
width:33%;
height:19%;
}
}
@-webkit-keyframes spin{
50%{
width:50%;
height:12%;
}
100%{
width:33%;
height:19%;
}
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
var elems = document.querySelectorAll("#list > div");
var arr = $.makeArray(elems);
arr.sort(function(a, b) {
return $(a).data("count") - $(b).data("count")
});
$(arr).appendTo("#list");
});
</script>
</head>
<body>
<div id="list">
<div data-count="7" class="col-xs-6 col-lg-4">07</div>
<div data-count="8" class="col-xs-6 col-lg-4">08</div>
<div data-count="9" class="col-xs-6 col-lg-4">09</div>
<div data-count="10" class="col-xs-6 col-lg-4">10</div>
<div data-count="11" class="col-xs-6 col-lg-4">11</div>
<div data-count="12" class="col-xs-6 col-lg-4">12</div>
<div data-count="1" class="col-xs-6 col-lg-4">01</div>
<div data-count="2" class="col-xs-6 col-lg-4">02</div>
<div data-count="3" class="col-xs-6 col-lg-4">03</div>
<div data-count="4" class="col-xs-6 col-lg-4">04</div>
<div data-count="5" class="col-xs-6 col-lg-4">05</div>
<div data-count="6" class="col-xs-6 col-lg-4">06</div>
<div data-count="13" class="col-xs-6 col-lg-4">13</div>
</div>
</body>
</html>
|
Цитата:
рони, прорисовка в моем скрипте итак уже реализована, проблема в том, что если количество элементов не кратно количеству столбцов, а, точнее, если один элемент "лишний", то нужно вставлять элемент-пустышку, а я не разобрался как... Что касается предложенного примера, то, к сожалению, длина списка заранее неизвестна, и может значительно отличаться, поэтому, я не могу указать высоту для #list, а без таковой Ваш пример не работает. |
onotole,
ваше css? |
onotole,
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
#list{
width:300px;
}
#list>div{
float: left;
width:32%;
height:50px;
border:1px #FF0033 solid;
text-align:center;
line-height:2em;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
var elems = document.querySelectorAll("#list > div");
var arr = $.makeArray(elems);
arr.sort(function(a, b) {
return $(a).data("count") - $(b).data("count")
});
function printNumbers(arr, cols) {
var fragment = document.createDocumentFragment();
var cNum = arr.length;
var step = Math.ceil(cNum / cols);
for (var i = 0; i < step; i++) {
fragment.appendChild(arr[i]);
for (var k = 1; k < cols; k++) {
var n = i + step * k;
if (n < cNum) fragment.appendChild(arr[n]);
else fragment.appendChild(document.createElement('div'))
}
}
return fragment
}
$(printNumbers(arr, 3)).appendTo("#list");
});
</script>
</head>
<body>
<div id="list">
<div data-count="7" class="col-xs-6 col-lg-4">07</div>
<div data-count="8" class="col-xs-6 col-lg-4">08</div>
<div data-count="9" class="col-xs-6 col-lg-4">09</div>
<div data-count="10" class="col-xs-6 col-lg-4">10</div>
<div data-count="11" class="col-xs-6 col-lg-4">11</div>
<div data-count="12" class="col-xs-6 col-lg-4">12</div>
<div data-count="1" class="col-xs-6 col-lg-4">01</div>
<div data-count="2" class="col-xs-6 col-lg-4">02</div>
<div data-count="3" class="col-xs-6 col-lg-4">03</div>
<div data-count="4" class="col-xs-6 col-lg-4">04</div>
<div data-count="5" class="col-xs-6 col-lg-4">05</div>
<div data-count="6" class="col-xs-6 col-lg-4">06</div>
<div data-count="13" class="col-xs-6 col-lg-4">13</div>
</div>
</body>
</html>
|
рони,
Благодарю, отличный пример, если других вариантов не останется, постараюсь задействовать его, вообще, же, полностью эмулируя среду bootstrap, сортировка поломалась
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
#list{
width:100%;
}
#list>div{
height:50px;
border:1px #FF0033 solid;
text-align:center;
line-height:2em;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
var elems = document.querySelectorAll("#list > div");
var arr = $.makeArray(elems);
arr.sort(function(a, b) {
return $(a).data("count") - $(b).data("count")
});
function printNumbers(arr, cols) {
var fragment = document.createDocumentFragment();
var cNum = arr.length;
var step = Math.ceil(cNum / cols);
for (var i = 0; i < step; i++) {
fragment.appendChild(arr[i]);
for (var k = 1; k < cols; k++) {
var n = i + step * k;
if (n < cNum) fragment.appendChild(arr[n]);
else fragment.appendChild(document.createElement('div'))
}
}
return fragment
}
$(printNumbers(arr, 3)).appendTo("#list");
});
</script>
</head>
<body>
<div class="container">
<div id="list">
<div data-count="7" class="col-xs-6 col-lg-4">07</div>
<div data-count="8" class="col-xs-6 col-lg-4">08</div>
<div data-count="9" class="col-xs-6 col-lg-4">09</div>
<div data-count="10" class="col-xs-6 col-lg-4">10</div>
<div data-count="11" class="col-xs-6 col-lg-4">11</div>
<div data-count="12" class="col-xs-6 col-lg-4">12</div>
<div data-count="1" class="col-xs-6 col-lg-4">01</div>
<div data-count="2" class="col-xs-6 col-lg-4">02</div>
<div data-count="3" class="col-xs-6 col-lg-4">03</div>
<div data-count="4" class="col-xs-6 col-lg-4">04</div>
<div data-count="5" class="col-xs-6 col-lg-4">05</div>
<div data-count="6" class="col-xs-6 col-lg-4">06</div>
<div data-count="13" class="col-xs-6 col-lg-4">13</div>
</div>
</div>
</body>
</html>
|
рони, немного переделал функцию, чтобы создаваемым пустышкам присваивались классы, и все заработало, ОГРОМНОЕ СПАСИБО!
function printNumbers(arr, cols) {
var fragment = document.createDocumentFragment();
var cNum = arr.length;
var step = Math.ceil(cNum / cols);
for (var i = 0; i < step; i++) {
fragment.appendChild(arr[i]);
for (var k = 1; k < cols; k++) {
var n = i + step * k;
if (n < cNum) fragment.appendChild(arr[n]);
else {
var div = document.createElement('div');
div.className = "col-xs-6 col-lg-4";
fragment.appendChild(div);
// fragment.appendChild(document.createElement('div'))
}
}
}
return fragment
}
|
Цитата:
смотреть пост 1 строку 50 |
| Часовой пояс GMT +3, время: 14:23. |