Shuffle only one child DIV based on class - javascript

I would like to shuffle specific DIVs (based on class) around on each page load.
Note i'm using a Wordpress Theme and as such, do not have full control over HTML structure without changing base themes (which i'm not willing to do)
jfiddle is here.
$(function() {
$(".shuffle").each(function() {
var parent = $(this),
divs = parent.children().remove();
while (divs.length) {
parent.append(divs.splice(Math.floor(Math.random() * divs.length), 1)[0]);
}
});
});
Parent DIV class = "shuffle"
Child DIVs class = "shuffle-child"
What am I doing wrong? Apologies for lack of JS experience!!

For your particular scenario you can use the following, adapted for jQuery from https://stackoverflow.com/a/11972692/2413733 #AlexeyLebedev's answer using the Fischer-Yates Shuffle.
var shuffleKids = $('.shuffle-kids'), // the elements to shuffle
shuffle = shuffleKids.parent(); // the container div
for (var i = shuffleKids.length; i >= 0; i--) {
shuffle.append(shuffle.children()[Math.random() * i | 0]);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='shuffle'>
<div class='shuffle-kids'>milk</div>
<div class='shuffle-kids'>butter</div>
<div class='shuffle-kids'>eggs</div>
<div class='shuffle-kids'>orange juice</div>
<div class='shuffle-kids'>bananas</div>
</div>

Related

Sorting Child Elements Based on 'h2' Tag

I have an an example page containing several categories. Each category is wrapped in a .items class which contains an h2 title tag and several links. My goal is to sort each of those categories alphabetically based on the h2 tag.
I found several examples on how to do this, but they were in jquery. I want to do this only in javascript. I found some code that will sort divs but not by the divs's h2 tag.
HTML
<div id="mainContainer" class="column-container row">
<div class="item column">
<h2>Testimonials</h2>
Testimonial slider
</div>
<div class="item column">
<h2>Directories</h2>
Staff Directory
</div>
<div class="item column">
<h2>FAQ</h2>
</div>
<div class="item column">
<h2>Forms</h2>
Simple contact form - WIP
Online payment form using Network Merchants - WIP
Form with attachment
</div>
</div>
JavaScript
sortCategory('#mainContainer');
function sortCategory(s) {
Array.prototype.slice.call(document.body.querySelectorAll(s)).sort(function sort (ea, eb) {
var a = ea.textContent.trim();
var b = eb.textContent.trim();
if (a < b) return -1;
if (a > b) return 1;
return 0;
}).forEach(function(div) {
div.parentElement.appendChild(div);
});
}
How can I modify the javascipt code to sort each .item by the h2 tag?
Solution
With the help of others I figured it out and wanted to share the code. I also formatted the code to be easily read.
//****************************************
// Sort Categories Alphabetically
//****************************************
function sortCategory(elementContainer)
{
var allElements = document.body.querySelectorAll(elementContainer);
Array.prototype.slice.call(allElements).sort(byAlphabet).forEach(function(div)
{
div.parentElement.appendChild(div);
});
}
function byAlphabet(first, second)
{
var order = 0;
var first = first.querySelector('h2').textContent.trim();
var second = second.querySelector('h2').textContent.trim();
first > second ? order = 1 : order = -1;
return order;
}
//Call sortCategory function and pass in the container you want sorted
sortCategory('#mainContainer>.item');
Change ea.textContent.trim() to ea.querySelector('h2').textContent.trim()
and
change eb.textContent.trim() to eb.querySelector('h2').textContent.trim()
This will basically say check each div's first H2 element, rather than the div.
Hope I was helpful!

Randomly select remaining divs Javascript

I have three divs with the attribute row. When the page loads I want to randomly select one of the divs and apply the class .show. From here, when the document is clicked I want one of the divs out of the remaining two divs to be randomly selected and have the class .show applied to it. When the document is clicked again, the last remaining div showed have .show applied to it. Now all three divs have the class .show. If the document is clicked again visual cycle should be restart so that only one randomly selected div has the class .show.
I've laid out (as a javascript novice) my approach but I don't know how to keep track of the rowArray which records which divs are remaining (the divs that DONT have the class .show) at each stage of the counter.
Any pointers in the right direction would be greatly appreciated. I have attached a JSFiddle with comments.
var selector = Math.floor((Math.random() * 3));
var rowArray = [0, 1, 2];
var counter = 0;
$(document).ready(function() {
counter++
$('#cnt').find("div[row=" + selector +"]").addClass('show');
var newrowArray = rowArray.splice(selector, 1);
$(document).on("click", function() {
counter++
if (counter ==1 ) {
} else if (counter == 2) {
} else {
counter = 1;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cnt">
<div row="0"></div>
<div row="1"></div>
<div row="2"></div>
</div>
you can make a function that selects all the elements that do not have show class, using this list select a randomIndex and then randomly add class show to one these elements. You can all this function on page load and from click on document.
$(document).ready(function() {
function selectDiv(){
var notSelectedDivs = $("div[row]:not(.show)");
if(!notSelectedDivs.length){
$('.show').removeClass('show');
notSelectedDivs = $("div[row]:not(.show)");
}
var randomIndex = Math.floor((Math.random() * notSelectedDivs.length));
$(notSelectedDivs[randomIndex]).addClass('show');
}
$(document).on("click", function() {
selectDiv();
});
selectDiv();
});
.show{
color: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cnt">
<div row="0">1</div>
<div row="1">2</div>
<div row="2">3</div>
</div>

swap 2 div's index using pure javascript

I have a parent div and it has 9 same div's am trying to swap two div's index. Following is my code:
HTML:
<div id="cont" class="container">
<div class="no">1</div>
<div class="no">2</div>
<div class="no">3</div>
<div class="blank"></div>
<div class="no">4</div>
<div class="no">5</div>
<div class="no">6</div>
<div class="no">7</div>
<div class="no">8</div>
</div>
now I want to swap say 5th and 6th indexed elements. I have no clue how to do that in JavaScript. I know there is function called .index() but how to do that in pure JS.
Here's one implementation: http://jsfiddle.net/x8hWj/2/
function swap(idx1, idx2) {
var container = document.getElementById('cont');
// ditch text nodes and the like
var children = Array.prototype.filter.call(
container.childNodes,
function(node) {
return node.nodeType === 1;
}
);
// get references to the relevant children
var el1 = children[idx1];
var el2 = children[idx2];
var el2next = children[idx2 + 1];
// put the second element before the first
container.insertBefore(el2, el1);
// now put the first element where the second used to be
if (el2next) container.insertBefore(el1, el2next);
else container.appendChild(el1);
}
This starts by getting a list of all element child nodes, then uses insertBefore to rearrange them.

Set div id's from array content

I'm trying to figure out how to give 16 different divs the id names that are stored in a 16 elements long array.
This is so that I can randomize the divs "placement" for a memory game, since there will be 8 different div styles that will change along with the div id if that is possible.
My plan is to have the same name for the div id as for the style for that specific div.
Is there any way to set the first div's id and style as the value in myarray[0], and the second div's id and style as myarray[1], and so on?
EDIT:
var card = ["orange","orange","pink","pink","red","red","purple","purple",
"blue","blue","green","green","brown","brown","yellow","yellow"];
for(var j, x, i = card.length; i; j = parseInt(Math.random() * i),
x = card[--i], card[i] = card[j], card[j] = x);
then later in the body I'm trying to achieve something that represents this:
<div id="card[0]"></div>
<div id="card[1]"></div>
<div id="card[2]"></div>
and so on...
Here is a solution for randomising class names using pure JavaScript.
Updated answer
I have updated my solution now that the question was clarified, here is it adapted to your colors. I have set the background-color of the .cards to the colors set in the array. This could easily be done using the id as well, I recommend against using [] characters in an id though as I think I'm not sure if that's standards compliant.
jsFiddle
var colors = [
"orange","orange","pink","pink","red","red","purple","purple",
"blue","blue","green","green","brown","brown","yellow","yellow"
];
var divs = document.getElementsByClassName("card");
while (divs.length > 0) {
var i = Math.floor(Math.random() * colors.length);
divs[0].style.backgroundColor = colors[i];
colors.splice(i, 1);
divs = [].slice.call(divs, 1);
}
Original answer
Given an array of ids and a set of HTML elements, a random id will be assigned to each element from ids.
jsFiddle
JavaScript
var ids = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var divs = document.getElementsByClassName("game-element");
while (divs.length > 0) {
var i = Math.floor(Math.random() * ids.length);
divs[0].id = 'item-' + ids[i];
ids.splice(i, 1);
divs = [].slice.call(divs, 1);
}
HTML
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
<div class="game-element"></div>
CSS
.game-element {
width:10px;
height:10px;
float:left;
}
#item-1 { background-color:#F00; }
#item-2 { background-color:#0F0; }
#item-3 { background-color:#00F; }
#item-4 { background-color:#FF0; }
#item-5 { background-color:#F0F; }
#item-6 { background-color:#0FF; }
#item-7 { background-color:#A0A; }
#item-8 { background-color:#0AA; }
#item-9 { background-color:#AA0; }
#item-10 { background-color:#000; }
Assign each div a randomdiv class or something like that. That will ensure you can select on the ones you want without affecting other divs.
Then you can do this
var idArr = [/**random ids here**/];
$( ".randomdiv" ).each(function( index ) {
$(this).attr("id",idArr[index]);
});
That will loop over every div with the class randomdiv and assign it a value from idArr which you can define however you want, I guess with some type of randomization function for your use case
Update
With your updates to the question I'm seeing an issue. You have non unique ids that you want to set. ids must be unique. If you want to assign multiple of them to be the same you want to use classes. So the code would instead look like this
var card = ["orange","orange","pink","pink","red","red","purple","purple",
"blue","blue","green","green","brown","brown","yellow","yellow"];
$( ".randomdiv" ).each(function( index ) {
$(this).addClass(card[index]);
});
And then you could define the style you want with css like this
.randomdiv.blue{
background-color:blue;
}
.randomdiv.green{
background-color:green;
}
...
Hard to know exactly what you're after but if using jQuery you could do something like this:
HTML:
<div class="random"></div>
<div class="random"></div>
<div class="random"></div>
JavaScript:
var myarray = ["one","two","three"];
// loop through all divs
$('div.random').each(function(index) {
// set div id to array value
$('div').attr('id', myarray[index]);
});
Result:
<div class="random" id="one"></div>
<div class="random" id="two"></div>
<div class="random" id="three"></div>
Additional Comments:
Would be worth ensuring or at least checking that the array length is equal to the number of div elements, otherwise you may receive exceptions.
Your page could be either rendered in server side or client side
1) in server side, that is much more easier with your server side language (e.g. C#) and framework (e.g. ASP.NET)
2) in client side, you could generate your DOM based on any JavaScript template (e.g. underscore template) and render it by passing the array as data model)
you may refer to underscore template method: http://underscorejs.org/#template
EDIT
for an example on server side (I use C# and MVC razor view as example, but it could be the same idea if you use any other language and web server).
#{ ids = ... }
#foreach (var id in ids)
{
<div id="#id"></div>
}
the code will help you to generate the div with ids you defined.
and on client side (I use underscore template, but again same idea if you use any other engine)
var list = "_.each(ids, function(id) {<div id='<%id%>'></div>});";
_.template(list, {ids: ['id1', 'id2', 'id3']});
this will generate 3 div with the ids listed.
Update
It's better to generate the id when generating the div rather than firstly generate the div then modify its id.

Shuffle all DIVS with the same class

What I need done is:
Original State:
<div class="shuffledv">
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
</div>
<div class="shuffledv">
<div id="4"></div>
<div id="5"></div>
<div id="6"></div>
</div>
After Shuffle:
<div class="shuffledv">
<div id="2"></div>
<div id="3"></div>
<div id="1"></div>
</div>
<div class="shuffledv">
<div id="5"></div>
<div id="4"></div>
<div id="6"></div>
</div>
The Divs within the first div stay there but get shuffled, and the same happens for the second div with the same class.
To shuffle divs inside a specific div I use something like this:
function shuffle(e) { // pass divs inside #parent to the function
var replace = $('<div>');
var size = e.size();
while (size >= 1) {
var rand = Math.floor(Math.random() * size);
var temp = e.get(rand); // grab a random div from #parent
replace.append(temp); // add the selected div to new container
e = e.not(temp); // remove our selected div from #parent
size--;
}
$('#parent').html(replace.html()); // add shuffled divs to #parent
}
Called lie this: shuffle('#parent .divclass')
Where all Divs with class divclass are inside #parent
I think it should start out something like
function shuffle() {
$(".shuffledv").each(function() {
and then do some form of the original function, but I've just gotten completely lost at this point. I have no idea how to go forward from here. Please let me know if you need anymore info.
Take a look at this jsfiddle. Essentially what we do is for each of the container shuffledv divs we find all children divs and store them in a list, then we remove them from the DOM, e.g.:
$(".shuffledv").each(function(){
var divs = $(this).find('div');
for(var i = 0; i < divs.length; i++) $(divs[i]).remove();
Then I grabbed the Fisher-Yates shuffling algorithm from here to randomise the list of our divs, and finally we append them back to the parent container, like this:
for(var i = 0; i < divs.length; i++) $(divs[i]).appendTo(this);
Hope this helps!
Gave this an initial run through:
(function () {
"use strict";
// Cycle over each .shuffledv HTMLElement
$(".shuffledv").each(function () {
// Remove all divs within, store in $d
var $d = $(this).find("div").remove();
// Sort $d randomnly
$d.sort(function () { return Math.floor(Math.random() * $d.length); });
// Append divs within $d to .shuffledv again
$d.appendTo(this);
});
}());
Demo: http://jsfiddle.net/uYyAH/2/

Categories