使用 jQuery 随机化一系列 div 元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1533910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 11:39:32  来源:igfitidea点击:

Randomize a sequence of div elements with jQuery

jqueryhtmlsortinghtml-manipulation

提问by vitto

I'm trying to do my frist steps with jQuery but I have some trouble to understand how to find a list of child elements from a div parent element. I'm used to work with ActionScript 2 and ActionScript 3 so i could mistake some concept, like what is the better way to randomize a sequence of div elements with jQuery!

我正在尝试使用 jQuery 完成我的第一步,但我在理解如何从 div 父元素中查找子元素列表时遇到了一些麻烦。我习惯于使用 ActionScript 2 和 ActionScript 3,所以我可能会误解一些概念,比如使用 jQuery 随机化一系列 div 元素的更好方法是什么!

I have this simple portion of HTML code:

我有这个简单的 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>

I have attempted some way to do that like map .memberdivs in one array and then changing the sort order but without success.

我尝试了某种方法来做到这一点,例如在一个数组中映射.memberdiv,然后更改排序顺序,但没有成功。

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"));

when i attempted to alert element_parent[0]i thought to get the first child of my .memberlist of divs but it isn't.

当我试图提醒element_parent[0] 时,我想得到我的.memberdiv 列表的第一个孩子,但事实并非如此。

if i make an alert with element_parent[0].innerHTMLi see that:

如果我使用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>

Why? How can I do to get exactly one of the members like this?

为什么?我该怎么做才能获得这样的成员之一?

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

I'm sure this should be easy but I just don't know how :(

我相信这应该很容易,但我只是不知道如何:(

please help
thanks
vittorio

请帮助
感谢
维托里奥



EDIT:

编辑:

Thanks for the fastness and this various ways to get the selected children, I'll take a note of these ways for the future!
I tried this methods, but it seems I couldn't get the entire div (please tell'me if i mistake something, it' could be too much possible!!).

感谢您的坚守和各种获得选中孩子的方式,我会记录这些方式以备将来!
我试过这种方法,但似乎我无法获得整个 div(如果我弄错了,请告诉我,这可能太多了!!)。

I shoud get this content:

我应该得到这个内容:

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

but with one of this methods like $("div.band div.member:eq(2)")or the other useful ways, I get this:

但是使用像$("div.band div.member:eq(2)")这样的方法之一或其他有用的方法,我得到了这个:

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

so is there a way to get the .memberdiv container too in my node?

那么有没有办法在我的节点中获取.memberdiv 容器?

回答by Russ Cam

$('div.band div.member');

will give you a jQuery object containing <div>that match the selector i.e. div with class memberthat are descendents of a div with class band.

将为您提供一个包含<div>匹配选择器的 jQuery 对象,即 div 与 classmember是div 与 class的后代band

The jQuery object is an array-like object in that each matched element is assigned a numerical property (think like an index) of the object and a lengthproperty is also defined. To get one element is

jQuery 对象是一个类似数组的对象,因为每个匹配的元素都被分配了一个对象的数字属性(想象成一个索引),并且length还定义了一个属性。得到一个元素是

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

or

或者

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

Instead of selecting all elements, you can specify to select a specific element according to position in the DOM. For example

您可以指定根据 DOM 中的位置选择特定元素,而不是选择所有元素。例如

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

or

或者

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

EDIT:

编辑:

Here's a plugin I just knocked out

这是我刚刚淘汰的插件

(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);

Working Code:

工作代码:

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

(function($) {

  $.fn.randomize = function(tree, childElem) {
    return this.each(function() {
      var $this = $(this);
      if (tree) $this = $(this).find(tree);
      var unsortedElems = $this.children(childElem);
      var elems = unsortedElems.clone();

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

      for (var i = 0; i < elems.length; i++)
        unsortedElems.eq(i).replaceWith(elems[i]);
    });
  };

})(jQuery);
body {
  background-color: #000;
  font: 16px Helvetica, Arial;
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="band">
  <table>
    <tr>
      <td>
        <div class="member">
          <ul>
            <li>John</li>
            <li>Lennon</li>
          </ul>
        </div>
      </td>
    </tr>
    <tr>
      <td>
        <div class="member">
          <ul>
            <li>Paul</li>
            <li>McCartney</li>
          </ul>
        </div>
      </td>
    </tr>
    <tr>
      <td>
        <div class="member">
          <ul>
            <li>George</li>
            <li>Harrison</li>
          </ul>
        </div>
      </td>
    </tr>
    <tr>
      <td>
        <div class="member">
          <ul>
            <li>Ringo</li>
            <li>Starr</li>
          </ul>
        </div>
      </td>
    </tr>
  </table>
</div>
<button>Randomize</button>

Here's an Editable Working Demo. add /editto the URL to see the code. If you need any details about how it works, please leave a comment. It could probably do with being made more robust to handle certain situations (like if there are other child elems of the jQuery object the plugin is chianed to) but it'll suit your needs.

这是一个可编辑的工作演示。将/edit添加到 URL 以查看代码。如果您需要有关其工作原理的任何详细信息,请发表评论。它可能会变得更健壮以处理某些情况(例如,如果插件连接到 jQuery 对象的其他子元素),但它会满足您的需求。

回答by gruppler

I modified Russ Cam's solution so that the selector is optional, and the function can be called on multiple container elements, while preserving each randomized element's parent.

我修改了 Russ Cam 的解决方案,以便选择器是可选的,并且可以在多个容器元素上调用该函数,同时保留每个随机元素的父元素。

For example, if I wanted to randomize all LIs within each '.member' div, I could call it like this:

例如,如果我想随机化每个 '.member' div 中的所有 LI,我可以这样称呼它:

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

I could also do it like this:

我也可以这样做:

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


So the two ways to call this are as follows:

所以这两种调用方式如下:

$(parent_selector).randomize(child_selector);

OR

或者

$(child_selector).randomize();


Here's the modified code:

这是修改后的代码:

$.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;
};

Minified:

缩小:

$.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};

回答by whitebrow

Randomization using sort does not always randomize the elements. It is better to use a shuffle method like the one from How can I shuffle an array?

使用 sort 的随机化并不总是随机化元素。最好使用类似于如何洗牌数组中的洗牌方法

Here's my updated code

这是我更新的代码

(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);