Рандомизировать последовательность элементов div с помощью jQuery - PullRequest
54 голосов
/ 08 октября 2009

Я пытаюсь выполнить свои первые шаги с помощью jQuery, но у меня возникают некоторые трудности с пониманием того, как найти список дочерних элементов из родительского элемента div. Я привык работать с ActionScript 2 и ActionScript 3, поэтому я мог ошибиться в некоторой концепции, например в том, как лучше рандомизировать последовательность элементов div с помощью jQuery!

У меня есть простая часть HTML-кода:

<div class="band">
    <div class="member">
        <ul>
            <li>John</li>
            <li>Lennon</li>
        </ul>
    </div>
    <div class="member">
        <ul>
            <li>Paul</li>
            <li>McCartney</li>
        </ul>
    </div>
    <div class="member">
        <ul>
            <li>George</li>
            <li>Harrison</li>
        </ul>
    </div>
    <div class="member">
        <ul>
            <li>Ringo</li>
            <li>Starr</li>
        </ul>
    </div>
</div>

Я попытался каким-то образом сделать это, например, map .member , делит один массив, а затем изменил порядок сортировки, но безуспешно.

function setArrayElements (element_parent) {
    var arr = [];
    //alert (element_parent[0].innerHTML);
    for (var i = 0; i < element_parent.children().length; i ++) {
        arr.push (element_parent[i].innerHTML);
    }
}
setArrayElements($(".band"));

когда я пытался предупредить element_parent [0] я думал, что получу первого ребенка в моем списке .member , но это не так.

если я сделаю предупреждение с element_parent [0] .innerHTML я вижу, что:

<div class="member">
    <ul>
        <li>John</li>
        <li>Lennon</li>
    </ul>
</div>
<div class="member">
    <ul>
        <li>Paul</li>
        <li>McCartney</li>
    </ul>
</div>
<div class="member">
    <ul>
        <li>George</li>
        <li>Harrison</li>
    </ul>
</div>
<div class="member">
    <ul>
        <li>Ringo</li>
        <li>Starr</li>
    </ul>
</div>

Почему? Как я могу сделать так, чтобы получить именно такого участника?

<div class="member">
    <ul>
        <li>Paul</li>
        <li>McCartney</li>
    </ul>
</div>

Я уверен, что это должно быть легко, но я просто не знаю, как (

помогите пожалуйста
спасибо
Витторио


EDIT:

Спасибо за быстроту и за разные способы получить отобранных детей, я запомню эти способы на будущее!
Я попробовал этот метод, но, похоже, я не смог получить весь div (пожалуйста, скажите мне, если я что-то ошибаюсь, это может быть слишком много !!).

Я должен получить это содержание:

<div class="member">
    <ul>
        <li>Ringo</li>
        <li>Starr</li>
    </ul>
</div>

, но с одним из этих методов, таких как $ ("div.band div.member: eq (2)") или другими полезными способами, я получаю это:

alert ($('div.band div.member')[0]);
/* result
<ul>
    <li>Ringo</li>
    <li>Starr</li>
</ul>
*/

так есть ли способ получить контейнер .member div тоже в моем узле?

Ответы [ 3 ]

94 голосов
/ 08 октября 2009
$('div.band div.member');

даст вам объект jQuery, содержащий <div>, который соответствует селектору, то есть div с классом member, который является потомком div с классом band.

Объект jQuery является массивоподобным объектом, в котором каждому сопоставленному элементу присваивается числовое свойство (например, индекс) объекта, а также определяется свойство length. Чтобы получить один элемент, это

// first element
$('div.band div.member')[0];

или

// first element
$('div.band div.member').get(0);

Вместо выбора всех элементов вы можете указать, чтобы выбрать конкретный элемент в соответствии с положением в DOM. Например

// get the first div with class member element
$("div.band div.member:eq(0)")

или

// get the first div with class member element
$("div.band div.member:nth-child(1)")

EDIT:

Вот плагин, который я только что отключил

(function($) {

$.fn.randomize = function(childElem) {
  return this.each(function() {
      var $this = $(this);
      var elems = $this.children(childElem);

      elems.sort(function() { return (Math.round(Math.random())-0.5); });  

      $this.detach(childElem);  

      for(var i=0; i < elems.length; i++)
        $this.append(elems[i]);      

  });    
}
})(jQuery);

Вот Рабочая демонстрация . добавьте / edit к URL, чтобы увидеть код. Если вам нужны подробности о том, как это работает, пожалуйста, оставьте комментарий. Вероятно, это может быть сделано с большей надежностью для обработки определенных ситуаций (например, если есть другие дочерние элементы объекта jQuery, к которому подключен плагин), но это будет соответствовать вашим потребностям.

Код из демки

$(function() {

  $('button').click(function() {
    $("div.band").randomize("div.member");
  });

});

(function($) {

$.fn.randomize = function(childElem) {
  return this.each(function() {
      var $this = $(this);
      var elems = $this.children(childElem);

      elems.sort(function() { return (Math.round(Math.random())-0.5); });  

      $this.remove(childElem);  

      for(var i=0; i < elems.length; i++)
        $this.append(elems[i]);      

  });    
}
})(jQuery);

HTML

<div class="band">
    <div class="member">
        <ul>
            <li>John</li>
            <li>Lennon</li>
        </ul>
    </div>
    <div class="member">
        <ul>
            <li>Paul</li>
            <li>McCartney</li>
        </ul>
    </div>
    <div class="member">
        <ul>
            <li>George</li>
            <li>Harrison</li>
        </ul>
    </div>
    <div class="member">
        <ul>
            <li>Ringo</li>
            <li>Starr</li>
        </ul>
    </div>
</div>
<button>Randomize</button>
25 голосов
/ 01 августа 2012

Я изменил решение Russ Cam, чтобы селектор был необязательным, и функцию можно было вызывать для нескольких элементов контейнера, сохраняя при этом родительский элемент каждого рандомизированного элемента.

Например, если бы я хотел рандомизировать все LI внутри каждого элемента '.member', я мог бы назвать это так:

$('.member').randomize('li');

Я мог бы сделать это так:

$('.member li').randomize();

Итак, есть два способа вызвать это следующим образом:

$(parent_selector).randomize(child_selector);

OR

$(child_selector).randomize();

Вот модифицированный код:

$.fn.randomize = function(selector){
    (selector ? this.find(selector) : this).parent().each(function(){
        $(this).children(selector).sort(function(){
            return Math.random() - 0.5;
        }).detach().appendTo(this);
    });

    return this;
};

уменьшенная:

$.fn.randomize=function(a){(a?this.find(a):this).parent().each(function(){$(this).children(a).sort(function(){return Math.random()-0.5}).detach().appendTo(this)});return this};
6 голосов
/ 05 августа 2014

Рандомизация с использованием сортировки не всегда рандомизирует элементы. Лучше использовать метод shuffle, например, из Как я могу перемешать массив?

Вот мой обновленный код

(function($) {
    $.fn.randomize = function(childElem) {
        function shuffle(o) {
            for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
            return o;
        };
        return this.each(function() {
            var $this = $(this);
            var elems = $this.children(childElem);

            shuffle(elems);

            $this.detach(childElem);  

            for(var i=0; i < elems.length; i++) {
                $this.append(elems[i]);      
            }
        });    
    }
})(jQuery);
...