skip to Main Content

I am trying to randomise the order of some children elements with a specific class inside a div that already contains other children elements.

I am using this, but I want to keep the order of the elements without this specific class rather than shuffle them all.

$(function () {
    var parent = $(".slider-thumbs .swiper-wrapper");
    var divs = parent.children();
    while (divs.length) {
        parent.append(divs.splice(Math.floor(Math.random() * divs.length), 1)[0]);
    }
});

Is there a way to shuffle children elements with an specific class without affecting the ones without this class?

Thanks

2

Answers


  1. Let’s brute force our way. Shuffle, check, repeat. Then push one by one to the original parent by the order of shuffling.

    function shuffle(a) {
      var j, x, i;
      for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
      }
      return a;
    }
    
    function did_only_free_moved(arr, original) {
      for (var i = 0; i < arr.length; i++) {
        if (original[i] == 0 && arr[i].classList.contains("free")) {
          return false;
        }
      }
      return true;
    }
    
    function shuffle_free_children(elem) {
      var arr = Array.prototype.slice.call(elem.children);
      var original = [];
      for (var i = 0; i < arr.length; i++) {
        original.push(arr[i].classList.contains("free") ? 1 : 0);
      }
      do {
        arr = shuffle(arr)
      } while (!did_only_free_moved(arr, original))
      var i = 0;
      while (i < arr.length) {
        elem.appendChild(arr[i]);
        i++
      }
    }
    
    function do_it() {
      shuffle_free_children(document.querySelector("ul"))
    }
    li {
      padding: 2px;
      margin: 2px;
    }
    
    .free {
      background: lightgreen;
    }
    <ul>
      <li>item 1</li>
      <li class="free">item 2</li>
      <li class="free">item 3</li>
      <li>item 4</li>
      <li class="free">item 5</li>
      <li>item 6</li>
      <li>item 7</li>
      <li class="free">item 8</li>
      <li class="free">item 9</li>
    </ul>
    
    <button onclick="do_it()">shuffle</button>
    Login or Signup to reply.
  2. I assumed you want children that without the specific class shuffle will remain at the same position.

    First give the shuffle class to the element that you want to included in the shuffle.

    <div>remain 1</div>
    <div>remain 2</div>
    <div class="shuffle">SHUFFLE 1</div>
    <div>remain 3</div>
    <div class="shuffle">SHUFFLE 2</div>
    <div class="shuffle">SHUFFLE 3</div>
    

    Get the children which should included in shuffle.

    const children = $(parent).children(".shuffle");
    

    Convert the children to array, perform shuffle.

    const shuffled = shuffleArray(children.toArray());
    

    Then loop through the original children, replace each child with rearranged child.

    children.each((currentIndex, child) => {
        $(child).replaceWith($(shuffled[currentIndex]).get(0).outerHTML);
    })
    

    Demo:

    function shuffle() {
      /* shuffle with Fisher-Yates algorith */
      const shuffleArray = array => {
        return array.reduce(
          (newArray, _, i) => {
            var random = i + (Math.floor(Math.random() * (newArray.length - i)));
            [newArray[random], newArray[i]] = [newArray[i], newArray[random]];
            return newArray;
          }, [...array]);
      };
    
      const shuffleChildren = (parentIndex, parent) => {
        /* first get children with class "shuffle" */
        const childs = $(parent).children(".shuffle");
    
        /* shuffle the children, return rearranged children */
        const shuffled = shuffleArray(childs.toArray());
    
        /* loop through each child */
        childs.each((currentIndex, child) => {
          /* replace the original child with new order child */
          $(child).replaceWith($(shuffled[currentIndex]).get(0).outerHTML);
        })
      };
    
      /* loop though multiple parent to do shuffle */
      $(".parent").each(shuffleChildren);
    }
    <button type="button" onclick="shuffle()">Shuffle</button>
    <div class="parent">
      <div>remain 1</div>
      <div>remain 2</div>
      <div class="shuffle">SHUFFLE 1</div>
      <div>remain 3</div>
      <div class="shuffle">SHUFFLE 2</div>
      <div class="shuffle">SHUFFLE 3</div>
      <div>remain 4</div>
      <div>remain 5</div>
      <div class="shuffle">SHUFFLE 4</div>
      <div>remain 6</div>
      <div class="shuffle">SHUFFLE 5</div>
      <div class="shuffle">SHUFFLE 6</div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search