Cannot set property 'src' of undefined at HTMLImageElement.changeImg [duplicate] - javascript

This question already has answers here:
Can multiple different HTML elements have the same ID if they're different elements?
(17 answers)
Closed 2 years ago.
In this code when I use [i] it does not work but if I use [0] or [1] instead of [i] it works.
I do not understand why [i] is not working with src.
HTML code
<div class="player">
<p >Player 1
</p>
<img id="myimg" src="images/dice6.png">
</div>
<div class="player">
<p> Player 2
</p>
<img id="myimg" src="images/dice6.png">
</div>
JS code
var images = ["images/dice1.png","images/dice2.png","images/dice3.png","images/dice4.png","images/dice5.png","images/dice6.png"];
for (var i = 0; i < document.querySelectorAll("#myimg").length; i++){
document.querySelectorAll("#myimg")[i].addEventListener("click", changeImg);
function changeImg(){
var randomNumber1 = Math.floor(Math.random() * images.length);
document.querySelectorAll("#myimg")[i].src = images[randomNumber1] ;
}
}

Don't use ID's double they had to be unique. Better use classes instead.
Edited Version
In the eventListener call a function for your changeImg. There get the random Image and use `this`to get the actual element and change the source.
Note: Because random in JS is not really random I added to search as long random as the image is the same like actual. Otherwise you had sometimes to click multiple for a change.
For testing it's better to see if you use the full_page link (in the upper right corner of the output window).
var images = ["https://media.flaticon.com/dist/min/img/home/kiranshastry.png","https://www.pokewiki.de/images/thumb/d/d5/Sugimori_848.png/250px-Sugimori_848.png","https://assets.pokemon.com/assets/cms2/img/pokedex/full/034.png","https://assets.pokemon.com/assets/cms2/img/pokedex/full/030.png"];
for (let i = 0; i < document.querySelectorAll(".myimg").length; i++){
document.querySelectorAll(".myimg")[i].addEventListener("click", changeImg);
}
function changeImg(){
let randomNumber1;
do {
randomNumber1 = Math.floor(Math.random() * images.length);
} while (this.src == images[randomNumber1]);
this.src = images[randomNumber1] ;
}
<div class="player">
<p >Player 1</p>
<img class="myimg" src="https://www.pokewiki.de/images/thumb/d/d5/Sugimori_848.png/250px-Sugimori_848.png">
</div>
<div class="player">
<p> Player 2</p>
<img class="myimg" src="https://assets.pokemon.com/assets/cms2/img/pokedex/full/034.png">
</div>

Related

Why is my code displaying NaN instead of an integer when attempting to display a Math.random value?

I am attempting to append a Math.random function to a data-crystal attribute on an image. When the image is clicked, it will display the randomly assigned number to the HTML page and continue to add upon itself each time it is clicked.
Here is the code code.
let currentScore = 0
let wins = 0
let losses = 0
let targetScore = 0
//function to assign number to crystals
$('#crystal1').append(`
data-crystal=${Math.floor(Math.random() * 25) }
`)
$('#crystal1').on('click', function (){
let crystalValue = $(this).attr('data-crystal')
crystalValue = parseInt(crystalValue)
crystalValue += currentScore
$('.scoreTotal').text(currentScore)
console.log(crystalValue)
})
Also, here is the related HTML.
<div class="row">
<h4 class="scoreTotal"></h4>
</div>
</div>
<div class="row">
<img id="crystal1" src="./assets/images/crystal_1.png" alt="crystal 1">
<img id="crystal2" src="./assets/images/crystal_2.png" alt="crystal 2">
<img id="crystal3" src="./assets/images/crystal_3.png" alt="crystal 3">
<img id="crystal4" src="./assets/images/crystal_4.png" alt="crystal 4">
</div>
</div>
When I console.log crystalValue, I get NaN, even though when I look at the HTML in my dev tools, the data-crystal is being properly appended. I've tried everything I can to fix it, but can't seem to correct it. This my first post on Stack Overflow, I'm sorry if this is a common question or too simple.
The correct way to set data-attributes to with jQuery's .data() method, not jQuery's .append() method which inserts HTML at the end of an Element.
The documentation states that jQuery's .data method will:
Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.
let currentScore = 0
let wins = 0
let losses = 0
let targetScore = 0
//function to assign number to crystals
$('#crystal1').data('crystal', Math.floor(Math.random() * 25));
console.log($('#crystal1').data('crystal'));
$('#crystal1').on('click', function (){
let crystalValue = $(this).data('crystal');
currentScore++;
crystalValue += currentScore;
$('.scoreTotal').text(crystalValue);
})
html, body{
padding: 10px;
}
img{
display: inline-block;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="row">
<h4 class="scoreTotal"></h4>
</div>
<div class="row">
<img id="crystal1" src="./assets/images/crystal_1.png" alt="crystal 1">
<img id="crystal2" src="./assets/images/crystal_2.png" alt="crystal 2">
<img id="crystal3" src="./assets/images/crystal_3.png" alt="crystal 3">
<img id="crystal4" src="./assets/images/crystal_4.png" alt="crystal 4">
</div>
</div>
Your not adding the data attribute correctly.
Using jQuery's append is for inserting content into the end of each element on the set of the matched elements.
You should use jQuery's data method.
$('#crystal1').data('crystal', Math.floor(Math.random() * 25));
This will set the data-crystal attribute on all matched elements with the desired value.
Here's a fiddle with a working code.

how to show random images when when click on button using javascript

I am new to javascript so don't have that much knowledge of js so I have requirement of generate random images when click on button, images are displaying using php(codeigniter framework) how to show random images on every click like a.jpg should come first sometimes last or b.jpg should come first or last
<img src="<?=base_url('assets/game/a.jpg')?>" style="width:120px;"><br>
<img src="<?=base_url('assets/game/b.jpg')?>" style="width:120px;"><br>
<img src="<?=base_url('assets/game/c.jpg')?>" style="width:120px;"><br>
<img src="<?=base_url('assets/game/d.jpg')?>" style="width:120px;"><br>
<img src="<?=base_url('assets/game/e.jpg')?>" style="width:120px;"><br>
<button class="btn btn-success clk_btn" onclick="myfunction">generate random imgaes</button>
Here is an example, just replace the div with your images, also you might want to change the numbers based on the amount of pictures.
function random () {
const randomNr = Math.random()*100;
const elements = document.querySelectorAll('div');
elements.forEach((el) => el.style.display = 'none')
if (randomNr < 34) {
elements[0].style.display = 'block';
} else if(randomNr < 64) {
elements[1].style.display = 'block';
} else {
elements[2].style.display = 'block';
}
}
div {
display: none;
}
<div>image1</div>
<div>image2</div>
<div>image3</div>
<button onclick="random()">switch</button>
You can try this code.
// Javascript
var images = [
"<?=base_url('assets/game/a.jpg')?>",
"<?=base_url('assets/game/b.jpg')?>",
"<?=base_url('assets/game/c.jpg')?>",
"<?=base_url('assets/game/d.jpg')?>",
"<?=base_url('assets/game/e.jpg')?>"
];
document.getElementById("my_button").addEventListener("click", function() {
document.getElementById("my_image").src = images[Math.floor(Math.random()*5)%5]
})
<!-- HTML -->
<button id="my_button">Generate random image</button>
<br>
<img id="my_image" style="width:120px;"/>
Documentation:
Math.random() - JavaScript | MDN
Math.floor() - JavaScript | MDN
A possibility is to hide all images by adding a "hidden" attribute and on the click, choose a random one and remove that "hidden" attribute ;)
let images = document.getElementsByTagName('img');
for(let i = 0; i < images.length; i++)
images[i].setAttribute('hidden', true);
function myfunction()
{
let images = document.getElementsByTagName('img');
for(let i = 0; i < images.length; i++)
images[i].setAttribute('hidden', true);
let rand = Math.floor(Math.random()*images.length);
images[rand].removeAttribute('hidden');
}
<img src="http://via.placeholder.com/350?text=A" style="width:120px;"><br>
<img src="http://via.placeholder.com/350?text=B" style="width:120px;"><br>
<img src="http://via.placeholder.com/350?text=C" style="width:120px;"><br>
<img src="http://via.placeholder.com/350?text=D" style="width:120px;"><br>
<img src="http://via.placeholder.com/350?text=E" style="width:120px;"><br>
<button class="btn btn-success clk_btn" onclick="myfunction()">generate random imgaes</button>
<p id="result"></p>

Insert image src into Javascript Array by Class Name

I'm trying to create a JavaScript that will randomize images on page refresh. I'm not really familiar with JS so I've been having a bit of trouble.
I've succeeded in building a successful program by hard coding the image url sources into the JS array, but this is not a possibility for what I am coding this for because the user will dictate what set of images will display. The user will not have access to the JS. So the array would get the image sources from the html. What I've been trying to do is use "getElementByClassName" and insert into the array by for loop. But it doesn't seem to be working. I'm sure there is a more efficient way to do this as well, so feel free to enlighten me.
Here is the code I have so far:
<!-- Images to put into JS Array -->
<img class="header" src="/image1.jpg" style="display: none;" />
<img class="header" src="/image2.jpg" style="display: none;" />
<img class="header" src="/image3.jpg" style="display: none;" />
<!-- Image placeholder -->
<img src="/image1.jpg" id="rotate" />
And the JavaScript in a separate document:
// Javascript code
window.onload = chooseHeader;
var imgs = document.getElementsByClassName("header");
var headers = new Array();
for (var i = 0; i < imgs.length; i++) {
headers.push(imgs[i].src);
}
function chooseHeader() {
rand = Math.floor((Math.random() * headers.length));
document.getElementById("rotate").src = headers[rand];
}
Any advice will be appreciated!
Your code is probably running before the DOM has loaded.
You don't actually need an Array for this, and since getElementsByClassName returns a "live list", you can fetch the images before they exist, and they'll appear when they're loaded in the document.
So if that's the case, a solution is to get the src directly from imgs.
window.onload = chooseHeader;
// live list
var imgs = document.getElementsByClassName("header");
function chooseHeader() {
var rand = Math.floor((Math.random() * imgs.length));
document.getElementById("rotate").src = imgs[rand].src;
}
<img class=header src="https://dummyimage.com/50/f00/fff.jpg">
<img class=header src="https://dummyimage.com/50/0f0/fff.jpg">
<img class=header src="https://dummyimage.com/50/00f/fff.jpg">
<br><br>
Rotate:
<br><br>
<img id=rotate src="">

Image change on currently hovered image based on class name - JavaScript

I'm trying to build a function with pure JavaScript to change an image source of currently hovered over image from a set of images with the same class. Nothing happens with the following code:
<section id="imgs">
<div class="boundary">
<img class="cage" src="cage.png" height="150px" />
</div>
<div class="boundary">
<img class="cage" src="cage.png" height="150px" />
</div>
<div class="boundary">
<img class="cage" src="cage.png" height="150px" />
</div>
<div class="boundary">
<img class="cage" src="cage.png" height="150px" />
</div>
</section>
And my JavaScript function:
<script language="JavaScript">
var x = document.getElementsByClassName("cage");
for (var i = 0; i < x.length; i++) {
x[i].onMouseOver = function () {
this.src = "cageF.png";
}
}
</script>
you need to take care of case sensitivity, use onmouseover instead of onMouseOver
var x = document.getElementsByClassName("cage");
for (var i = 0; i < x.length; i++) {
x[i].onmouseover = function () {
this.src = "cageF.png";
}
}
Demo
I understand you have answer to your question. Have a look on below links to understand JavaScript better.
JavaScript case-sensitive
JavaScript is case-sensitive and uses the Unicode character set.
JavaScript mouseover event

javascript replace url link loop

I am a beginner for Javascript, read several post here but could not get my codes work. Hope you can explain the solution :)
So basically I have four set of images, but I need to replace all of the $_12.JPGto $_57.JPG in their URL so I get bigger size of pictures (only images that are assigned to class="ebay" / id="ebay"). I need this to be executed when the browser starts reading the page, no events or buttons involved.
The following is my source code:
<div>
<img class="ebay" id="ebay" u="image" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/neAAAOSwrklU28I8/$_12.JPG?set_id=880000500F">
<img u="thumb" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/neAAAOSwrklU28I8/$_12.JPG?set_id=880000500F">
</div>
<div>
<img class="ebay" id="ebay" u="image" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/r8cAAOSwNSxU28I9/$_12.JPG?set_id=880000500F">
<img u="thumb" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/r8cAAOSwNSxU28I9/$_12.JPG?set_id=880000500F">
</div>
<div>
<img class="ebay" id="ebay" u="image" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/HLgAAOSwPhdU28I-/$_12.JPG?set_id=880000500F">
<img u="thumb" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/HLgAAOSwPhdU28I-/$_12.JPG?set_id=880000500F">
</div>
<div>
<img class="ebay" id="ebay" u="image" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/6VkAAOSwPYZU28I-/$_12.JPG?set_id=880000500F">
<img u="thumb" src="http://i.ebayimg.com/00/s/NzgwWDc4MA==/z/6VkAAOSwPYZU28I-/$_12.JPG?set_id=880000500F">
</div>
I also like to loop the function so when I have more than 4 sets of pictures (maximum 15 sets) and the javascript can still replace the URL for me.
The following is what I had tried:
window.onload = function() {
for ( var i = 0; i < currentLink.length; i++) {
var currentLink=document.getElementByClassName('ebay');
var newLink = currentLink.src.replace('$_12.JPG','$_57.JPG');
currentLink.src = newLink;
}
}
You have to realize that getElementsByClassName returns an HTMLCollection, not a single element. So you cannot simply change all the elements in the collection by accessing the .src property of the collection.
You need to iterate over the collection to do this:
var currentLinks = document.getElementsByClassName('ebay');
Array.prototype.forEach.call(currentLinks, function(currentLink) {
var newLink = currentLink.src.replace('$_12.JPG','$_57.JPG');
currentLink.src = newLink;
});
Also, you have a typo in your getElementByClassName (you're missing the s in Elements).
See MDN
Misplacement of var currentLink=document.getElementByClassName('ebay');
Do,
window.onload = function() {
var currentLink=document.getElementsByClassName('ebay');
for ( var i = 0; i < currentLink.length; i++) {
var newLink = currentLink[i].src.replace('$_12.JPG','$_57.JPG');
currentLink[i].src = newLink;
}
}

Categories

Resources