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
CodePudding user response:
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 >item 2</li>
<li >item 3</li>
<li>item 4</li>
<li >item 5</li>
<li>item 6</li>
<li>item 7</li>
<li >item 8</li>
<li >item 9</li>
</ul>
<button onclick="do_it()">shuffle</button>
CodePudding user response:
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 >SHUFFLE 1</div>
<div>remain 3</div>
<div >SHUFFLE 2</div>
<div >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 >
<div>remain 1</div>
<div>remain 2</div>
<div >SHUFFLE 1</div>
<div>remain 3</div>
<div >SHUFFLE 2</div>
<div >SHUFFLE 3</div>
<div>remain 4</div>
<div>remain 5</div>
<div >SHUFFLE 4</div>
<div>remain 6</div>
<div >SHUFFLE 5</div>
<div >SHUFFLE 6</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>