Swap images from an array on button click - javascript

I have a small problem trying to create a script that changes the images in the array. The main objective is to show 10 pictures when you click on the button. Clicking on the next button starts mixing all the 10 pictures and not leaving. It should be done without jQuery. Thanks for the advices.
HTML
<button value="show" id="Show">Show Images</button>
<button value="swap" id="Swap" onclick="swapimg()">Swap Images</button>
<div id="image"></div>
<ul>
</ul>
JS
var ul = document.querySelector('ul');
var buttons = document.querySelector('#Show');
buttons.addEventListener('click', add);
var img = ["a.jpg","b.jpg","c.jpg","d.jpg","e.jpg","f.jpg","g.jpg","h.jpg","i.jpg","j.jpg"];
function add() {
for(var i=0; i<10; i++) {
var li = document.createElement('li');
var img1 = document.createElement('img');
img1.src=img[i];
ul.appendChild(li);
li.appendChild(img1);
buttons.style.display = "none";
}
}
function swapimg() {
var myImage1 = new Array();
myImage1[1] = "a.jpg";
myImage1[2] = "b.jpg";
myImage1[3] = "c.jpg";
myImage1[4] = "d.jpg";
myImage1[5] = "e.jpg";
myImage1[6] = "f.jpg";
myImage1[7] = "g.jpg";
myImage1[8] = "h.jpg";
myImage1[9] = "i.jpg";
myImage1[10] = "j.jpg";
var random = Math.floor(Math.random() * myImage1.length);
document.getElementById("image").innerHTML = "<img src='"
+ myImage1[random] + "' alt='image'></img>";
}

You could use a random function that shuffle in every click to gives you a random array that could be used to generate rando images :
function swapimg() {
var random = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].sort(function() {
return .5 - Math.random();
});
ul.innerHTML = "";
for (var i = 0; i < random.length; i++) {
add(random[i]);
}
}
Snippet:
var ul = document.querySelector('ul');
var buttons = document.querySelector('#Show');
buttons.addEventListener('click', addImg);
var img = ["a.jpg", "b.jpg", "c.jpg", "d.jpg", "e.jpg", "f.jpg", "g.jpg", "h.jpg", "i.jpg", "j.jpg"];
function addImg() {
ul.innerHTML = "";
for (var i = 0; i < 10; i++) {
add(i);
}
}
function add(i) {
var li = document.createElement('li');
var img1 = document.createElement('img');
img1.src = img[i];
img1.alt = img[i];
ul.appendChild(li);
li.appendChild(img1);
buttons.style.display = "none";
}
function swapimg() {
var random = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].sort(function() {
return .5 - Math.random();
});
ul.innerHTML = "";
for (var i = 0; i < random.length; i++) {
add(random[i]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button value="show" id="Show">Show Images</button>
<button value="swap" id="Swap" onclick="swapimg()">Swap Images</button>
<div id="image"></div>
<ul>
</ul>

The problem is that you are not shuffling. With a random number, you could find that you have repeated images. I made something similar a couple of months ago. The following code shuffles a list. Hope it helps:
function shuffle(list) {
if(list.length <= 1) return list;
const first = list.splice(list.length/2);
if(Math.random() > 0.5) return suffle(first).concat(shuffle(list));
else return suffle(list).concat(suffle(first));
}
This code divides the list in half until you got only one element, and then it starts merging it again but with a 50% chance of swaping the given lists.

Related

How to use for loop to sum a numbers inserted by the user?

i'm trying to create a simple project where the user is prompted to enter how many numbers he would like to add(sum). then when he click the button, a javascript will create a number of input tags equal to the number he inserted and then he will fill them with a number and click another button to calculate the result of the summation and here is the problem. below is a simplified snippet explain what is the problem:
function CL(){
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type","text");
inpt.setAttribute("style","margin:5px;");
inpt.setAttribute("id","y"+i);
inpt.setAttribute("value","");
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
}
function Add(){
const y = 0;
const sum = 0;
var is;
for (var i = 1; i < 3; i++) {
is = i.toString();
y = Number(document.getElementById('y'+ is).value);
sum = sum + y;
}
document.getElementById("demo").innerHTML = sum;
}
in the for loop how can i use getElementById with variables id like item1,item2,item3,...,itemN??
is there other way to achieve what i want?
You can take all items with ID "y" + consecutive number prefix on this way document.getElementById('y' + i).value;
Do not use "Add" for function name and Functions do not have to start with capital letters!
calckStart();
function calckStart() {
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type", "text");
inpt.setAttribute("style", "margin:5px;");
inpt.setAttribute("id", "y" + i);
inpt.setAttribute("value", "");
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
var button = document.createElement('button');
button.innerHTML = 'ClickMe'
items.appendChild(button);
button.addEventListener('click', calculateVal);
}
function calculateVal() {
var res = 0;
for (var i = 1; i < 3; i++) {
res = res + +document.getElementById('y' + i).value;
}
var items = document.getElementById("items");
var result = document.createElement('div');
result.innerHTML = res;
items.appendChild(result);
}
<div id="items"></div>
A better way is ...
When you create elements, you can assign them a CLASS attribute that is one for all input elements. You can then take the values from all elements with this class.
Example:
calckStart();
function calckStart() {
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type", "text");
inpt.setAttribute("style", "margin:5px;");
// inpt.setAttribute("id", "y" + i);
inpt.setAttribute("value", "");
inpt.setAttribute("class", "numbers"); //<-- Set class
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
var button = document.createElement('button');
button.innerHTML = 'ClickMe'
items.appendChild(button);
button.addEventListener('click', calculateVal);
}
function calculateVal() {
var list = document.getElementsByClassName('numbers'); //<-- Get by class
var res = 0;
for (var i = 0; i < list.length; i++) {
res = res + +list[i].value;
}
var items = document.getElementById("items");
var result = document.createElement('div');
result.innerHTML = res;
items.appendChild(result);
}
<div id="items"></div>
You can use ...args to collect arguments and use .reduce to add the arguments together.
const items = document.getElementById("items");
for (var i = 0; i < 3; i++) {
var inpt = document.createElement("input");
inpt.setAttribute("type","number"); //replaced with number
inpt.setAttribute("style","margin:5px;");
inpt.setAttribute("id","y"+i);
inpt.setAttribute("value","");
var newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline); //added newline appending
}
function sum(...args) {
return args.reduce((a, b) => a+b); //reduce arguments
}
<div id="items"></div><br /><button onclick="document.getElementById('answer').textContent = 'answer: ' + sum(+y0.value, +y1.value, +y2.value)">Add</button><div id="answer"></div>

Counter Using Javascript, HTML & CSS Not Working

Can anyone help me to get this (https://jsfiddle.net/hmatrix/v3jncqac/) code to work?
Inentention: I want to create a counter that increases in increments.
My HTML:
<body onload="incrementCount(10)">
<div class="main_container" id="id_main_container">
<div class="container_inner" id="display_div_id">
</div>
</div>
</body>
My JS:
var counter_list = [10,10000,10000];
var str_counter_0 = counter_list[0];
var str_counter_1 = counter_list[1];
var str_counter_2 = counter_list[2];
var display_str = "";
var display_div = document.getElementById("display_div_id");
function incrementCount(current_count){
setInterval(function(){
// clear count
while (display_div.hasChildNodes()) {
display_div.removeChild(display_div.lastChild);
}
str_counter_0++;
if (str_counter_0 > 99) {
str_counter_0 = 0; // reset count
str_counter_1++; // increase next count
}
if(str_counter_1>99999){
str_counter_2++;
}
display_str = str_counter_2.toString() + str_counter_1.toString() + str_counter_0.toString();
for (var i = 0; i < display_str.length; i++) {
var new_span = document.createElement('span');
new_span.className = 'num_tiles';
new_span.innerText = display_str[i];
display_div.appendChild(new_span);
}
},1000);
}
<body onload="incrementCount(10)">
<div class="main_container" id="id_main_container">
<div class="container_inner" id="display_div_id">
</div>
</div>
</body>
<script>
var counter_list = [10,10000,10000];
var str_counter_0 = counter_list[0];
var str_counter_1 = counter_list[1];
var str_counter_2 = counter_list[2];
var display_str = "";
var display_div = document.getElementById("display_div_id");
function incrementCount(current_count){
setInterval(function(){
// clear count
while (display_div.hasChildNodes()) {
display_div.removeChild(display_div.lastChild);
}
str_counter_0++;
if (str_counter_0 > 99) {
str_counter_0 = 0; // reset count
str_counter_1++; // increase next count
}
if(str_counter_1>99999){
str_counter_2++;
}
display_str = str_counter_2.toString() + str_counter_1.toString() +
str_counter_0.toString();
for (var i = 0; i < display_str.length; i++) {
var new_span = document.createElement('span');
new_span.className = 'num_tiles';
new_span.innerText = display_str[i];
display_div.appendChild(new_span);
}
},1000);
}
</script>
JSFIDDLE: https://jsfiddle.net/v3jncqac/32/
Your onload function cannot find the function because your js is in a different file. you need to add script src on top of html or do it as shown above.

using Javascript how to display element one by one on click

how to display element one by one on click using only Javascript, in my example when I click all elements show at once, but i need only one click - one element. I appreciate if you show the simplest way to do if in order to i can understand how it works
$(function() {
var cars = ["audi", "bmw", "volvo"];
var x = "";
var i;
for (i = 0; i <cars.length; i++) {
x += cars[i] + "<br>";
}
document.getElementById("btn").onclick = function() {
document.getElementById("text").innerHTML = x;
}
});
You may update your code as follows. At the very beginnig, your are initializing x with empty string. Then for each click on button, append an element from array with new line tag.
var cars = ["audi", "bmw", "volvo"];
var x = "";
var i = 0;
document.getElementById("btn").onclick = function() {
if( i < cars.length) {
x += cars[i++] + "<br>";
}
document.getElementById("text").innerHTML = x;
}
<p id="text"></p>
<button id="btn">Result</button>
<html>
<script>
var cars = ["audi", "bmw", "volvo"];
var x = "";
var count = 0;
function appendArray(){
if(count<cars.length){
x += cars[count]+ "<br>";
document.getElementById("appendText").innerHTML = x;
count++;
}else{
count = 0;
document.getElementById("appendText").innerHTML = "";
}
}
</script>
<p id="appendText"></p>
<button onclick="appendArray()">Submit</button>
</html>
Here is one solution in vanilla javascript:
var button = document.getElementsByTagName('button')[0];
var i = 0;
function addCar(i) {
var cars = ['audi', 'bmw', 'volvo'];
var paragraph = document.getElementsByTagName('p')[0];
if (i < cars.length) {
var newLine = document.createElement('br');
var newCar = document.createTextNode(cars[i]);
paragraph.appendChild(newLine);
paragraph.appendChild(newCar);
}
}
button.addEventListener('click',function(){addCar(i); i++;},false);
<p></p>
<button>Click for a New Car</button>

Nesting immediately invoked functions Javascript

I have a program which stores images and their names in an array. The names are displayed in a list, the corresponding image is displayed on click
I also want to count the clicks on the image once it is displayed. At a later point per image, right now I am just trying to count total clicks.
The code below does not display the clicks in the Console, I do not get any error.
Is it not possible to nest two immediately invoked functions like this?
for (var i = 0; i < cats.length; i++) {
//Building the list . Creating a list item and textnode. The textnode reads out the catnames. Append the textnode to the list. Append all of it to the catlist in the HTML
var catitem = document.createElement("LI");
var textnode = document.createTextNode(cats[i].id);
catitem.appendChild(textnode);
document.getElementById("catlist").appendChild(catitem);
//Adding the catname to the div
var currentcat = cats[i].id;
var currentimage = cats[i].img;
catitem.addEventListener('click', (function(currentimage_copy) {
return function() {
var clicks = 0;
var x = document.createElement("IMG");
x.setAttribute("src", currentimage_copy);
var item = document.getElementById("catimage");
var y = document.getElementById("catimage").childNodes[0];
item.replaceChild(x, y);
x.setAttribute("onclick", (function countClicks(clickscopy) {
return function countClicks() {
clicks++;
console.log(clickscopy);
};
})(clicks));
Here is the full code
<!DOCTYPE html>
<html>
<body>
<title>||Cats||</title>
</head>
<body>
<h1>This is the list of cats<h1>
<h2>Click the cat to see an image of the cat</h2>
<ul id="catlist">
</ul>
<div id="catimage">
</div>
<div id="catname"></div>
<div id="current"></div>
<script>
document.body.onload = addElement;
function addElement() {
var cats = [{
img: "cat.jpg",
id: "cleo"
},
{
img: "shimi.png",
id: "shimi"
},
{
img: "miezi.png",
id: "miezi"
},
{
img: "tom.jpg",
id: "tom"
},
{
img: "chrissie.jpg",
id: "chrissie"
}
];
for (var i = 0; i < cats.length; i++) {
//Building the list . Creating a list item and textnode. The textnode reads out the catnames. Append the textnode to the list. Append all of it to the catlist in the HTML
var catitem = document.createElement("LI");
var textnode = document.createTextNode(cats[i].id);
catitem.appendChild(textnode);
document.getElementById("catlist").appendChild(catitem);
//Adding the catname to the div
var currentcat = cats[i].id;
var currentimage = cats[i].img;
catitem.addEventListener('click', (function(currentimage_copy) {
return function() {
var clicks = 0;
var x = document.createElement("IMG");
x.setAttribute("src", currentimage_copy);
var item = document.getElementById("catimage");
var y = document.getElementById("catimage").childNodes[0];
item.replaceChild(x, y);
x.setAttribute("onclick", (function countClicks(clickscopy) {
return function countClicks() {
clicks++;
console.log(clickscopy);
};
})(clicks));
};
})(currentimage));
}
}
</script>
</body>
</html>
Use addEventListener instead of setAttribute
Try this:
var cats = [{
id: 1,
img: 'https://jsfiddle.net/img/logo.png'
}, {
id: 2,
img: 'https://www.google.co.in/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
}, ]
for (var i = 0; i < cats.length; i++) {
//Building the list . Creating a list item and textnode. The textnode reads out the catnames. Append the textnode to the list. Append all of it to the catlist in the HTML
var catitem = document.createElement("LI");
var textnode = document.createTextNode(cats[i].id);
catitem.appendChild(textnode);
document.getElementById("catlist").appendChild(catitem);
//Adding the catname to the div
var currentcat = cats[i].id;
var currentimage = cats[i].img;
catitem.addEventListener('click', (function(currentimage_copy) {
return function() {
var clicks = 0;
var x = document.createElement("IMG");
x.setAttribute("src", currentimage_copy);
var item = document.getElementById("catimage");
var y = document.getElementById("catimage").childNodes[0];
item.replaceChild(x, y);
x.addEventListener("click", (function countClicks(clickscopy) {
return function countClicks() {
clickscopy++;
console.log(clickscopy);
};
})(clicks));
}
})(currentimage))
}
<ul id='catlist'></ul>
<div id='catimage'>
<img src="" alt="">
</div>

How to ssign Variable with div element's name

So I got multiple divs with different images embedded. Each one has its unique name attributes. I'm trying to apply the hover effect to each divs by changing the image source. I don't want to write multiple scripts, rather I'm trying to write a just one block of script that would effect every div.
<div id="div1" >
<img id="img1" name="img1" src="img1_up.jpg" />
</div>
<div id="div2">
<img id="img2" name="img2" src="img2_up.jpg" />
</div>...and so on
Now here is the script that I currently have for the rollover effects
<script>
var var1 = document.getElementById("div1");
var1.addEventListener("mouseover", changeImage1);
var1.addEventListener("mouseout", restoreImage1);
function changeImage1() {
document.getElementById("img1").src = "img1_ro.jpg";
}
function restoreImage1() {
document.getElementById("img1").src = "img1_up.jpg";
}
var var2 = document.getElementById("div2");
var2.addEventListener("mouseover", changeImage2);
var2.addEventListener("mouseout", restoreImage2);
function changeImage2() {
document.getElementById("img2").src = "img2_ro.jpg";
}
function restoreImage2() {
document.getElementById("img2").src = "img2_up.jpg";
}...and so on
</script>
I would like to use the name attributes from each images to create dynamic code to apply to all images. Here is what I have in mind but not sure the exact way to write it. PLEASE HELP
...
var dynamicVar = ????
dynamicVar.addEventListener("mouseover", changeImage();
dynamicVar.addEventListener("mouseout", restoreImage();
function changeImage() {
document.getElementById(dynamicVar).src = dynamicVar + "_ro.jpg";
}
function restoreImage() {
document.getElementById(dynamicVar).src = dynamicVar + "_up.jpg";
}
You can use loop to add event, don't need to specify id for each div:
var inputs = document.getElementsByTagName("div");
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].id.indexOf('div') >= 0) {
inputs[i].addEventListener("mouseover", changeImage);
inputs[i].addEventListener("mouseout", restoreImage);
}
}
function changeImage(){
var tmpStr = this.id;
var divIndex = tmpStr.substring(3, tmpStr.length);
document.getElementById("img" + divIndex).src = divIndex + "_ro.jpg";
}
function restoreImage(){
var tmpStr = this.id;
var divIndex = tmpStr.substring(3, tmpStr.length);
document.getElementById("img" + divIndex).src = divIndex + "_up.jpg";
}
See on fiddle: Link
try this
var parent = document.getElementById("parent");
var childs = parent.getElementsByTagName('div');
for (var i = 0; i < childs.length; i++) {
(function () {
var e = childs[i];
e.addEventListener("mouseover", function () {
changeImage(e);
});
e.addEventListener("mouseout", function () {
restoreImage(e);
});
}());
}
function changeImage(element) {
var imgs = element.getElementsByTagName('img');
for (var i = 0; i < imgs.length; i++) {
alert(imgs[i].id);
}
}
function restoreImage(element) {
var imgs = element.getElementsByTagName('img');
for (var i = 0; i < imgs.length; i++) {
imgs[i].src = img_ro;
}
}
you can check this fiddle

Categories

Resources