24.02.2015, 23:54
|
Новичок на форуме
|
|
Регистрация: 24.02.2015
Сообщений: 6
|
|
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);
}
Не знаю, насколько данный код оптимален, но он работает, за исключением того, что я не придумал как добавить новый элемент пустышку
|
|
25.02.2015, 00:00
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
РНР знаете? Есть в нем функция разбивающая массив на части array_chunk(), правда вывод будет не так как у вас, а
1 2 3
4 5 6
7 8
Если пойдет, то js-аналог ее здесь найдете.
|
|
25.02.2015, 00:42
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
|
|
25.02.2015, 01:52
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
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>
|
|
25.02.2015, 11:45
|
Новичок на форуме
|
|
Регистрация: 24.02.2015
Сообщений: 6
|
|
Сообщение от laimas
|
РНР знаете? Есть в нем функция разбивающая массив на части array_chunk(), правда вывод будет не так как у вас, а
1 2 3
4 5 6
7 8
Если пойдет, то js-аналог ее здесь найдете.
|
Элементы с float:left будут следовать в указанном Вами порядке и без разбиения. Но порядок должен быть не слева направо, а сверху вниз.
рони, прорисовка в моем скрипте итак уже реализована, проблема в том, что если количество элементов не кратно количеству столбцов, а, точнее, если один элемент "лишний", то нужно вставлять элемент-пустышку, а я не разобрался как...
Что касается предложенного примера, то, к сожалению, длина списка заранее неизвестна, и может значительно отличаться, поэтому, я не могу указать высоту для #list, а без таковой Ваш пример не работает.
Последний раз редактировалось onotole, 25.02.2015 в 11:47.
|
|
25.02.2015, 12:20
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
onotole,
ваше css?
|
|
25.02.2015, 14:37
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
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>
|
|
25.02.2015, 19:43
|
Новичок на форуме
|
|
Регистрация: 24.02.2015
Сообщений: 6
|
|
рони,
Благодарю, отличный пример, если других вариантов не останется, постараюсь задействовать его, вообще, же, полностью эмулируя среду 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>
|
|
25.02.2015, 19:55
|
Новичок на форуме
|
|
Регистрация: 24.02.2015
Сообщений: 6
|
|
рони, немного переделал функцию, чтобы создаваемым пустышкам присваивались классы, и все заработало, ОГРОМНОЕ СПАСИБО!
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
}
|
|
25.02.2015, 19:55
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Сообщение от onotole
|
сортировка поломалась
|
попробуйте ответить почему сами и исправить
смотреть пост 1 строку 50
|
|
|
|