Любой способ перемешать содержимое в нескольких элементах div

Я относительно новичок в 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. Но на самом деле это не случайным образом. Это просто заставляет вещи идти по кругу (что может быть нормально).

Мы ценим любые предложения. Спасибо.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
7
0
12 018
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Я бы обернул 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>

Это не отвечает на вопрос, а просто объясняет другой способ перемещения контента.

Joel Anair 24.11.2008 23:20

Я предложил быстрый способ перемещения содержимого, что является первоначальным намерением OP. Что вы прочитали, чтобы задать вопрос?

Rob Allen 24.11.2008 23:24

Для этого я бы использовал код на стороне сервера. Я знаю, что это не ответ на ваш вопрос, но это является альтернативная реализация.

С уважением,
Франк

Ответ принят как подходящий

вы согласны с использованием библиотеки 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') );

Спасибо, Оуэн, я думаю, что это лучший ответ, который я когда-либо видел.

Chris 24.11.2008 23:37

К сожалению, поскольку моя репутация ниже 15, я не могу проголосовать за это. Но если бы я мог, я бы сделал это.

Chris 24.11.2008 23:38

Вы можете получить содержимое каждого 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 разрешил вопросы иметь несколько «принятых» ответов, я бы также пометил это как «принятый».

Chris 15.03.2012 23:20

это также применимо к списку перетасовки?

user962206 08.04.2012 06:33

@ gilly3 Вопрос о "divs.splice (Math.floor (Math.random () * divs.length), 1) [0]", какова польза от [0]?

user962206 08.04.2012 08:55

@ user962206 - .splice() возвращает массив, содержащий, в данном случае, единственный элемент. [0] возвращает вам первый элемент в этом массиве.

gilly3 09.04.2012 03:34

@ user962206 - да, вы можете использовать это, чтобы перетасовать список любых элементов.

gilly3 09.04.2012 03:37

Но splice удаляет контент, верно? и возвращает удаленные предметы?

user962206 09.04.2012 08:24

@ user962206 - Да в том-то и дело. Обратите внимание на цикл while ... мы выполняем цикл до тех пор, пока массив не станет пустым и все элементы не будут повторно вставлены.

gilly3 09.04.2012 22:34

@ user962206 - Я обновил свой ответ, указав, что именно происходит внутри цикла while. Надеюсь, это поможет вам прояснить ситуацию.

gilly3 10.04.2012 04:19

когда цикл действительно остановится? разве цикл не остановится, поскольку в массиве divs всегда будет одна запись или один элемент?

user962206 10.04.2012 08:09

@ user962206 - Нет, помните, что .splice() удаляет элемент из массива. Поскольку на каждой итерации цикла while мы удаляем ровно один элемент из массива, цикл завершится, как только мы обработаем каждый элемент. divs - это массив, элементы которого ссылаются на внутренние узлы. Мы создали этот массив, скопировав элементы из коллекции родительского элемента children. Удаление элемента из массива не изменяет DOM. Т.е. вызов divs.splice(n, 1) удаляет элемент из массива, но элемент все еще существует на странице как дочерний для parent.

gilly3 10.04.2012 08:37

Расширяя хороший ответ на @ 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, который не масштабируется линейно с количеством элементов.

Другие вопросы по теме