Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 24.02.2015, 23:54
Новичок на форуме
Отправить личное сообщение для onotole Посмотреть профиль Найти все сообщения от onotole
 
Регистрация: 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);
}



Не знаю, насколько данный код оптимален, но он работает, за исключением того, что я не придумал как добавить новый элемент пустышку
Ответить с цитированием
  #2 (permalink)  
Старый 25.02.2015, 00:00
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

РНР знаете? Есть в нем функция разбивающая массив на части array_chunk(), правда вывод будет не так как у вас, а

1 2 3
4 5 6
7 8

Если пойдет, то js-аналог ее здесь найдете.
Ответить с цитированием
  #3 (permalink)  
Старый 25.02.2015, 00:42
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

onotole,
Прорисовать цифры в определенном порядке.
Ответить с цитированием
  #4 (permalink)  
Старый 25.02.2015, 01:52
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

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>
Ответить с цитированием
  #5 (permalink)  
Старый 25.02.2015, 11:45
Новичок на форуме
Отправить личное сообщение для onotole Посмотреть профиль Найти все сообщения от onotole
 
Регистрация: 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.
Ответить с цитированием
  #6 (permalink)  
Старый 25.02.2015, 12:20
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

onotole,
ваше css?
Ответить с цитированием
  #7 (permalink)  
Старый 25.02.2015, 14:37
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

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>
Ответить с цитированием
  #8 (permalink)  
Старый 25.02.2015, 19:43
Новичок на форуме
Отправить личное сообщение для onotole Посмотреть профиль Найти все сообщения от onotole
 
Регистрация: 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>
Ответить с цитированием
  #9 (permalink)  
Старый 25.02.2015, 19:55
Новичок на форуме
Отправить личное сообщение для onotole Посмотреть профиль Найти все сообщения от onotole
 
Регистрация: 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
}
Ответить с цитированием
  #10 (permalink)  
Старый 25.02.2015, 19:55
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Сообщение от onotole
сортировка поломалась
попробуйте ответить почему сами и исправить
смотреть пост 1 строку 50
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
быстрая отрисовка элементов JS (DOM) Brook Events/DOM/Window 2 18.07.2014 00:53
Собрать массив из элементов DOM Fairy-Wilbury Events/DOM/Window 4 13.09.2013 17:30
prototype DOM элементов simple Элементы интерфейса 6 02.03.2013 17:44
Сортировка элементов страницы frutality jQuery 2 08.02.2013 14:24
Получить список ВСЕХ элементов DOM Почемучкин Events/DOM/Window 7 16.04.2012 11:33