2

我正在使用这个问题中的一个函数来使用 jQuery 对表的行进行洗牌。我真正想要的是只洗牌第一列,其余部分保持不变,如下所示:

a b c d
e f g h
i j

对此:

e b c d
i f g h
a j

Rob W 的回答中的功能是:

(function($){
    //Shuffle all rows, while keeping the first column
    //Requires: Shuffle
 $.fn.shuffleRows = function(){
     return this.each(function(){
        var main = $(/table/i.test(this.tagName) ? this.tBodies[0] : this);
        var firstElem = [], counter=0;
        main.children().each(function(){
             firstElem.push(this.firstChild);
        });
        main.shuffle();
        main.children().each(function(){
           this.insertBefore(firstElem[counter++], this.firstChild);
        });
     });
   }
  /* Shuffle is required */
  $.fn.shuffle = function() {
    return this.each(function(){
      var items = $(this).children();
      return (items.length)
        ? $(this).html($.shuffle(items))
        : this;
    });
  }

  $.shuffle = function(arr) {
    for(
      var j, x, i = arr.length; i;
      j = parseInt(Math.random() * i),
      x = arr[--i], arr[i] = arr[j], arr[j] = x
    );
    return arr;
  }
})(jQuery)

但这与我想要的相反——它打乱了除第一列之外的所有。我怎样才能改变它,使它洗牌第一列?

4

1 回答 1

2

Here's what I came up with:

var $firstCells = $("#tableIdHere tr td:first-child"),
    $copies = $firstCells.clone(true);

[].sort.call($copies, function() { return Math.random() - 0.5; });

$copies.each(function(i){
    $firstCells.eq(i).replaceWith(this);
});

That is, select all the first cells using the :first-child selector, make a copy of them, and sort the copies randomly. Then loop through the (now randomised) copies and replace the originals with them.

Demo: http://jsfiddle.net/nnnnnn/ceTmL/

P.S. Note that this technique will randomly sort any collection of table cells or elements if you just change the selector that creates the $firstCells jQuery object, e.g., if you change the selector to "#tableIdHere tr" it will randomly sort the rows.

UPDATE:

"I cannot understand what the [] does?"

JavaScript arrays have a .sort() method that allows you to pass in a custom sort comparison function like the one I used above that returns a random number between -0.5 and +0.5 to sort in random order. But jQuery objects are not arrays so you can't just say $copies.sort(...) on the $copies jQuery object. However, jQuery objects are like arrays in that they have numerically indexed elements and a length property, and some array methods (including .sort()) can be called on array-like objects if you use the .call() or .apply() methods to call them. I could've said:

Array.prototype.sort.call($copies, ...

...but instead I went with the easier to type:

[].sort.call($copies, ...

...where [] is just an empty array that is there solely to provide access to the array .sort() method. The sort will be applied to the object that is the first parameter to .call, not to the empty array.

于 2012-09-04T06:55:28.650 回答