Я относительно новичок в Javascript, и мне было интересно, есть ли быстрый способ перетасовать контент, содержащийся в нескольких тегах <div>. Например
<div id='d1'>
<span>alpha</span>
<img src='alpha.jpg'>
</div>
<div id='d2'>
<span>beta</span>
<img src='beta.jpg'>
</div>
<div id='d3'>
<span>gamma</span>
<img src='gamma.jpg'>
</div>
<button onclick='shuffle_content();'>Shuffle</button>
После нажатия на кнопку я бы хотел, чтобы содержимое в d1, d2, d3 поменялось местами (например, может быть, сначала будет d3, затем d1, затем d2).
Быстрый способ перемещать объекты - скопировать первый элемент div (d1), затем поместить его в самый конец (после d3), а затем удалить исходный d1. Но на самом деле это не случайным образом. Это просто заставляет вещи идти по кругу (что может быть нормально).
Мы ценим любые предложения. Спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я бы обернул div во внешний div, а затем передал его идентификатор в shuffle_content ().
Там вы можете создать новый div, клонирование - узлы div-оболочки в случайном порядке, чтобы заполнить их, а затем заменять - div-оболочку с новым div.
Я бы посоветовал вам рандомизировать контент, а не сами Div. Вы можете сделать это, разместив контент на отдельных html-страницах - без информации заголовка или тела, только контент.
Затем используйте функцию при загрузке страницы, чтобы случайным образом назначить, какой div какой контент получает, и используйте это для изменения содержимого DIV:
<script type = "text/javascript">
function ajaxManager(){
var args = ajaxManager.arguments;
if (document.getElementById) {
var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
}
if (x){
switch (args[0]){
case "load_page":
if (x)
{
x.onreadystatechange = function()
{
if (x.readyState == 4 && x.status == 200){
el = document.getElementById(args[2]);
el.innerHTML = x.responseText;
}
}
x.open("GET", args[1], true);
x.send(null);
}
break;
case "random_content":
ajaxManager('load_page', args[1], args[2]); /* args[1] is the content page, args[2] is the id of the div you want to populate with it. */
break;
} //END SWITCH
} //END if (x)
} //END AjaxManager
</script>
Я предложил быстрый способ перемещения содержимого, что является первоначальным намерением OP. Что вы прочитали, чтобы задать вопрос?
Для этого я бы использовал код на стороне сервера. Я знаю, что это не ответ на ваш вопрос, но это является альтернативная реализация.
С уважением,
Франк
вы согласны с использованием библиотеки javascript, такой как jQuery? вот краткий пример jQuery для выполнения того, что вам нужно. единственная модификация вашего HTML - это добавление предложенного элемента контейнера:
<div id = "shuffle">
<div id='d1'>...</div>
<div id='d2'>...</div>
<div id='d3'>...</div>
</div>
и javascript:
function shuffle(e) { // pass the divs to the function
var replace = $('<div>');
var size = e.size();
while (size >= 1) {
var rand = Math.floor(Math.random() * size);
var temp = e.get(rand); // grab a random div from our set
replace.append(temp); // add the selected div to our new set
e = e.not(temp); // remove our selected div from the main set
size--;
}
$('#shuffle').html(replace.html() ); // update our container div with the
// new, randomized divs
}
shuffle( $('#shuffle div') );
Спасибо, Оуэн, я думаю, что это лучший ответ, который я когда-либо видел.
К сожалению, поскольку моя репутация ниже 15, я не могу проголосовать за это. Но если бы я мог, я бы сделал это.
Вы можете получить содержимое каждого div
c1 = document.getElementById('div1').innerHTML
c2 = document.getElementById('div2').innerHTML
c3 = document.getElementById('div3').innerHTML
Затем случайным образом определите для них новый порядок ... и затем поместите каждый контент в новое место назначения.
скажем, например, случайность дала:
c1_div = 'div2'
c2_div = 'div1'
c3_div = 'div3'
тогда вы просто:
document.getElementById(c1_div).innerHTML = c1
document.getElementById(c2_div).innerHTML = c2
document.getElementById(c3_div).innerHTML = c3
Для вашего HTML краткий ответ на ваш вопрос:
function shuffle_content() {
var divA = new Array(3);
for(var i=0; i < 3; i++) {
divA[i] = document.getElementById('d'+(i+1));
document.body.removeChild(divA[i]);
}
while (divA.length > 0)
document.body.appendChild(divA.splice(Math.floor(Math.random() * divA.length),1)[0]);
}
Чтобы добраться туда, я написал следующее, что, как мне кажется, работает лучше:
<html>
<div id = "cards">
<div id = "card0">Card0</div><div id = "card1">Card1</div>
<div id = "card2">Card2</div><div id = "card3">Card3</div>
<div id = "card4">Card4</div><div id = "card5">Card5</div>
<div id = "card6">Card6</div><div id = "card7">Card7</div>
<div id = "card8">Card8</div><div id = "card9">Card9</div>
</div>
<button id = "shuffle">Shuffle</button>
<script language = "javascript">
<!--
document.getElementById('shuffle').onclick = function () {
var divCards = document.getElementById('cards');
var divCardsArray = new Array(
document.getElementById('card0'),
document.getElementById('card1'),
document.getElementById('card2'),
document.getElementById('card3'),
document.getElementById('card4'),
document.getElementById('card5'),
document.getElementById('card6'),
document.getElementById('card7'),
document.getElementById('card8'),
document.getElementById('card9')
);
return function() {
var mDivCardsArray=divCardsArray.slice();
while (divCards.childNodes.length > 0) {
divCards.removeChild(divCards.firstChild);
}
while (mDivCardsArray.length > 0) {
var i = Math.floor(Math.random() * mDivCardsArray.length);
divCards.appendChild(mDivCardsArray[i]);
mDivCardsArray.splice(i,1);
}
return false;
}
}()
//-->
</script>
</html>
Я пытался упаковать это последнее заявление while, чтобы:
while (mDivCardsArray.length > 0) {
divCards.appendChild(
mDivCardsArray.splice(
Math.floor(Math.random() * mDivCardsArray.length)
,1)[0]
);
}
но это довольно сложно читать и подвержено ошибкам.
Используя jQuery или Prototype, вы можете следовать той же базовой структуре и получить желаемый результат.
Лично я думаю, что это выглядит еще лучше, если вы добавите еще 2 div в стек cards, развернете divCardsArray, вставите следующий блок стиля и добавите этот код сразу после определения divCardsArray.
<html>
...
<style>
html,body{height:100%;width:100%;text-align:center;font-family:sans-serif;}
#cards,#cards div{padding:5px;margin:5px auto 5px auto;width:100px;}
</style>
...
<div id = "cardA">CardA</div><div id = "cardB">CardB</div>
...
var colorCardsArray = new Array(
'#f00', '#f80', '#ff0', '#8f0', '#0f0', '#0f8',
'#0ff', '#08f', '#00f', '#80f', '#f0f', '#f08' );
for(var i=0;i<divCardsArray.length;i++)
divCardsArray[i].style.backgroundColor=colorCardsArray[i];
...
</html>
Недавний вопрос был просто закрыт как дубликат этого, но я чувствую, что получил лучший ответ, чем любой здесь. Этот метод очень прямой. При копировании HTML нет никакого мусора, что позволяет сохранить изменения в DOM, стилях, обработчиках событий и т. д.
Чтобы перемешать все дочерние элементы какого-либо родительского элемента, выберите случайный дочерний элемент и добавляйте его обратно к родительскому элементу по одному, пока все дочерние элементы не будут повторно добавлены.
Используя jQuery:
var parent = $("#shuffle");
var divs = parent.children();
while (divs.length) {
parent.append(divs.splice(Math.floor(Math.random() * divs.length), 1)[0]);
}
Демо:http://jsfiddle.net/C6LPY/2
Без jQuery это похоже и так же просто:
var parent = document.getElementById("shuffle");
var divs = parent.children;
var frag = document.createDocumentFragment();
while (divs.length) {
frag.appendChild(divs[Math.floor(Math.random() * divs.length)]);
}
parent.appendChild(frag);
Демо:http://jsfiddle.net/C6LPY/5/
Редактировать: Вот фрагмент кода:
// Create a document fragment to hold the shuffled elements
var frag = document.createDocumentFragment();
// Loop until every element is moved out of the parent and into the document fragment
while (divs.length) {
// select one random child element and move it into the document fragment
frag.appendChild(divs[Math.floor(Math.random() * divs.length)]);
}
// appending the document fragment appends all the elements, in the shuffled order
parent.appendChild(frag);
Хороший ответ. Если бы Stackoverflow разрешил вопросы иметь несколько «принятых» ответов, я бы также пометил это как «принятый».
это также применимо к списку перетасовки?
@ gilly3 Вопрос о "divs.splice (Math.floor (Math.random () * divs.length), 1) [0]", какова польза от [0]?
@ user962206 - .splice() возвращает массив, содержащий, в данном случае, единственный элемент. [0] возвращает вам первый элемент в этом массиве.
@ user962206 - да, вы можете использовать это, чтобы перетасовать список любых элементов.
Но splice удаляет контент, верно? и возвращает удаленные предметы?
@ user962206 - Да в том-то и дело. Обратите внимание на цикл while ... мы выполняем цикл до тех пор, пока массив не станет пустым и все элементы не будут повторно вставлены.
@ user962206 - Я обновил свой ответ, указав, что именно происходит внутри цикла while. Надеюсь, это поможет вам прояснить ситуацию.
когда цикл действительно остановится? разве цикл не остановится, поскольку в массиве divs всегда будет одна запись или один элемент?
@ user962206 - Нет, помните, что .splice() удаляет элемент из массива. Поскольку на каждой итерации цикла while мы удаляем ровно один элемент из массива, цикл завершится, как только мы обработаем каждый элемент. divs - это массив, элементы которого ссылаются на внутренние узлы. Мы создали этот массив, скопировав элементы из коллекции родительского элемента children. Удаление элемента из массива не изменяет DOM. Т.е. вызов divs.splice(n, 1) удаляет элемент из массива, но элемент все еще существует на странице как дочерний для parent.
Расширяя хороший ответ на @ gilly3, используя jQuery, можно фактически избежать добавления случайно выбранных элементов divs в цикл, вместо этого случайно sorting div и append добавляя их все сразу:
$(function() {
var parent = $("#shuffle");
var divs = parent.children();
divs.sort(function(a, b) {
return 0.5 - Math.random();
});
parent.append(divs);
});
Демо: http://jsfiddle.net/ey70Lxhk/
Однако обратите внимание, что этот метод не является точным с точки зрения случайности и основан на sort, который не масштабируется линейно с количеством элементов.
Это не отвечает на вопрос, а просто объясняет другой способ перемещения контента.