using javascript in html to delete things when clicked - javascript

I have previously posted about this page Im trying to create and Im still running into errors. I am very new to this and getting confused. I need to use a for loop to loop over the images and assign an event listener to each one so that when they are clicked on they get deleted. Im getting confused with the difference variables and pulling the html into my javascript. I keep getting ".addEventListener is not a function" and so I keep changing things but getting lost.
<!DOCTYPE html>
<html>
<body>
<div id = 'img'>
<img src="https://www.sciencemag.org/sites/default/files/styles/article_main_large/public/dogs_16x9_0.jpg?itok=byPuhQjh" id="img"/>
<img src="https://www.yvr.ca/-/media/yvr/blog/2018/57_yvr_puppies_2018.jpg" id="img"/>
</div>
<script text="javascript">
let images = document.querySelectorAll("img");
for (let i = 0; i < images.length; i++){
images[i].addEventListener("click", () => {
images[i].remove();
});
}
</script>
</body>
</html>

You are accessing array directly, which won't have the addEventListener. Try images[i].addEventListener

images.addEventListener should be images[i].addEventListener. You want to add the listener to the specific image from the array, not the array itself. Similar problem with images.remove().

First, you have same id for your container and both of your images - ID is supposed to be unique.
Second, as people already mentioned, you can not attach eventListener to array of objects.
Something like this shoud do:
let images = document.querySelectorAll("[id^='img']");
for (let i = 0; i < images.length; i++){
images.forEach(i=>{i.addEventListener("click", () => {
i.remove();
});
});
}
<div id = 'box'>
<img src="https://www.sciencemag.org/sites/default/files/styles/article_main_large/public/dogs_16x9_0.jpg?itok=byPuhQjh" id="img1"/>
<img src="https://www.yvr.ca/-/media/yvr/blog/2018/57_yvr_puppies_2018.jpg" id="img2"/>
</div>

you cannot attach an event handler to a list of images
so loop over images and for each of them
// for each image in images
image.onclick = function (e) {
e.target.parentNode.removeChild(e.target);

This will help you - https://jsfiddle.net/n5mk9Lzj/
let images = document.querySelectorAll("img");
for (let i = 0; i < images.length; i++) {
images[i].addEventListener("click", function() {
images[i].remove();
});
}

You need to update your code, you are not using index inside loop.You cannot add any listener on directly to images array.
<!DOCTYPE html>
<html>
<body>
<div id = 'img'>
<img src="https://www.sciencemag.org/sites/default/files/styles/article_main_large/public/dogs_16x9_0.jpg?itok=byPuhQjh" id="img"/>
<img src="https://www.yvr.ca/-/media/yvr/blog/2018/57_yvr_puppies_2018.jpg" id="img"/>
</div>
<script text="javascript">
let images = document.querySelectorAll("img");
for (let i = 0; i < images.length; i++){
images[i].addEventListener("click", () => {
images[i].remove();
});
}
</script>
</body>
</html>

Related

The array won't work with the output of my pictures

I tried to show pictures with an array so I can change it per delay, kinda like a slideshow. The problem is, that only the first picture will load. when the counter of the array changes, the picture won't load.
The paths of the images are all correct
<!DOCTYPE html>`enter code here`
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test2</title>
<script>
var bilder = [];
var zeit = 3000;
var p = 0;
bilder[0] = "../Bilder/Bild1.jpg";
bilder[1] = "../Bilder/Bild2.jpg";
bilder[2] = "../Bilder/Bild3.jpg";
bilder[3] = "../Bilder/Bild4.jpg";
function BildAutoWeiter()
{
document.bild.src = bilder[p];
for( var i=0; i<= bilder.length; i++)
{
if(i <= bilder.length)
{
p++;
}
else
{
i = 0;
}
}
setTimeout("BildAutoWeiter()", zeit);
}
</script>
</head>
<body onload="BildAutoWeiter()">
<div>
<img name ="bild" width="100%" height="50%">
</div>
</body>
</html>
You need to use getElementsByName() to choose elements by their name=''. That returns an array of elements that use that name, so to choose a specific one, use an index [index] starting from 0. Do this instead:
document.getElementsByName('bild')[0].src = bilder[p];
That selects the first element that uses name='bild'
Also, the for statement is a bit useless. You could instead do:
function BildAutoWeiter()
{
document.bild.src = bilder[p];
p++;
setTimeout(BildAutoWeiter, zeit);
}
You don't need to put the function name in quotations and you can't have the parentheses while calling the function in setTimeout.

querySelectorAll is not working with data-srcset

I want to apply a class to all the horizontal imgs on the website.
I'm trying to use this function below but it doesn't work.
Any help would be greatly appreciated.
$(function() {
var images = document.querySelectorAll('[data-srcset]');
for (var i = 0; i < images.length; i++) {
if (images[i].naturalWidth > images[i].naturalHeight) {
$(images[i]).addClass('horizontal');
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-srcset="https://cdn.pixabay.com/photo/2015/02/18/11/50/mountain-landscape-640617_960_720.jpg" alt=landscape>
That is because the data:... image you provide is 1x1 and so the check for images[i].naturalWidth > images[i].naturalHeight fails.
Keep in mind that if you use the srcset attribute (instead of data-srcset) which is the default it will work as expected (but you need to use the load event of the page).
$(window).load(function() {
var images = document.querySelectorAll('[srcset]');
for (var i = 0; i < images.length; i++) {
if (images[i].naturalWidth > images[i].naturalHeight) {
$(images[i]).addClass('horizontal');
}
}
})
.horizontal{border:10px solid OliveDrab;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" srcset="http://www.dummyimage.com/400x200" alt=landscape>
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" srcset="http://www.dummyimage.com/200x210" alt=landscape>
It's better to replace alt=landscape with alt="landscape".
both
var images = document.querySelectorAll('[data-srcset]');
and
var images = $('[data-srcset]');
works for me.
Your problem is if statement is not true. it's always go to else.
Try update your if statement by the following code.
if (images[i].naturalWidth > images[i].naturalHeight) {
$(images[i]).addClass('horizontal');
console.log(images[i]);
} else {
console.log('else');
}
You'll see that it's always go to else.

Can you generate html locally, without using a server?

I'm trying to show images in a local html file using a loop. This is what I want it to show in the web browser:
<div id="polybridges">
<img src="polybridge_1.gif">
<img src="polybridge_2.gif">
<img src="polybridge_3.gif">
<img src="polybridge_4.gif">
<img src="polybridge_5.gif">
</div>
This is my attempt to do this with javascript:
<script>
for(var i = 1; i <= 5; i++) {
var elem = document.createElement("img");
elem.src='polybridge_'+i+'.gif';
document.getElementById("polybridges").appendChild(elem);
}
</script>
<div id="polybridges">
This doesn't generate anything. Is there a way to show images in a loop without using a server / localhost?
At first your element must be defined before script execution (so change the order). I suppose you want to append elem (instead of "hallo" string):
<div id="polybridges"></div>
<script>
for(var i = 1; i <= 5; i++) {
var elem = document.createElement("img");
elem.src='polybridge_'+i+'.gif';
document.getElementById("polybridges").appendChild(elem);
}
</script>
Put your images in the same directory as your html file.
for(var i = 1; i <= 5; i++) {
var elem = document.createElement("img");
elem.src='polybridge_'+i+'.gif';
document.getElementById("polybridges").appendChild(elem);
}
And change the argument for appendChild.
As malix states in his comment, you should use document.getElementById("polybridges").appendChild(elem); instead of document.getElementById("polybridges").appendChild("hallo"); (so append the element instead of string "hallo").
And, as the rest states, the images should be where you tell the browser they are.
Yes you can display images without server, you have to have that images in same directory as your html file or in images folder which in same level as your html file ( for that case images would be available as <img src="images/polybridge_5.gif">
appendChild take Node as parameter (not string)
for(var i = 1; i <= 5; i++) {
var elem = document.createElement("img");
elem.src='polybridge_'+i+'.gif';
document.getElementById("polybridges").appendChild(elem);
}
You need to take care of one thing. You are trying to get element by ID. So you need to make sure that html is valid. Provide proper close tag for the element. Also use the elem variable in the appendChild().
for (var i = 1; i <= 5; i++) {
var elem = document.createElement("img");
elem.src = 'polybridge_' + i + '.gif';
console.log(elem)
document.getElementById("polybridges").appendChild(elem);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="polybridges"></div>

Determing which element was clicked

I have a html like:
<div class="clicked-div" onclick="divClicked(this);">
<img src="src1"/>
<img src="src2"/>
......
</div>
if I set the img onclick event using the following method:
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].onClick=imageClicked(imgs[i]);
}
function divClicked(div){
alert(div.getAttribute("id"));
}
function imageClicked(image){
alert(image.getAttribute("src"));
}
when the uiwebview load one image, it will call imageClicked a time though I haven't click it.
And when I click a image ,how do I determing which method will be called divClicked or imageClicked? THank you.
Your code is calling imageClicked at the point you're trying to just set it up as a handler.
It's actually easier than you think it is:
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].onclick = imageClicked; // <=== Not *calling*, just referring to it
}
function imageClicked() {
alert(this.getAttribute("src")); // <== `this` rather than `image`
}
When imageClicked is called in response to the click event, it's called with this set to the image element that was clicked.
How to prevent the div to handle the click event when the image was clicked
Instead of onclick, you use modern event handling and stop propagation. As you're using a uiWebView, you don't have to worry about old IE, which makes things simpler:
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].addEventListener("click", imageClicked, false);
}
function imageClicked(e) {
alert(this.getAttribute("src"));
e.stopPropagation(); // <=== Prevents the click reaching the div
}
Live example:
// Hook up the divs so we handle clicks on them
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
divs[i].onclick = divClicked; // <=== Not *calling*, just referring to it
}
function divClicked() {
alert("div clicked");
}
// The images code
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].addEventListener("click", imageClicked, false);
}
function imageClicked(e) {
alert(this.getAttribute("src"));
e.stopPropagation();
}
<div>
<img src="https://www.gravatar.com/avatar/2cd48a51689add31036ce202cc020255?s=32&d=identicon&r=PG&f=1">
</div>
<div>
<img src="https://www.gravatar.com/avatar/760b4da77fd54d37c104029ff1f56749?s=32&d=identicon&r=PG">
</div>
<div>
<img src="https://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG">
</div>
<div>
No image in this one, so you can see it handle clicks
</div>
Side note: Although you can use onClick in your HTML, when you're using it in JavaScript, it has to be onclick (all lower case). I've made that change above in the version that still used it.

Confused about passing multiple images to Image() objects

I think I'm missing an obvious rule here and it would be great to get it clarified -
I'm trying to write an image preloader and I'm following the advice given on this posting:
Preloading images in Javascript? Without jQuery
I can see how it all works up until:
for(var i = 0; i < imageList.length; i++ ) {
var imageObject = new Image();
imageObject.src = imageList[i]; }
I keep thinking this would simply change/overwrite the src property at every iteration, leaving imageObject.src as the last image in the list at the end of the loop, though clearly the function is meant for using multiple images.
So I'm assuming it leaves imageObject containing an array of images but I'm not sure how it does this. What do I have wrong?
What you have will "probably" work. But, it's not the ideal way to do things because it relies on some undocumented aspects of a browser and garbage collection. See here and here for safer ways to do this. I'll try to explain what your code is doing.
When you do this line:
var imageObject = new Image();
it is creating a new DOM image object and placing a reference to that object in the variable imageObject.
When you do this line:
imageObject.src = imageList[i];
it is assigning the .src property of that new image object. This will NOT be overwriting the .src property on the previous image object.
But, because the previous image objects are not stored anywhere and no other javascript has any references to them, they are available for garbage collection by the browser and it is free to get rid of them at any time. To use this for reliable caching, you are hoping that the browser does not cancel the networking operation in progress that is loading the images and you are hoping that they still get into the browser cache so they are preloaded.
It is much safer to store the imageObject in an array as the other solutions I've pointed you to will do. This keeps them from being garbage collected so there is no risk that their image loading will be cancelled.
For example, it would be safer to do this:
var imgs = [];
for (var i = 0; i < imageList.length; i++ ) {
var imageObject = new Image();
imageObject.src = imageList[i];
imgs.push(imageObject);
}
The previous two references to other solutions to this do something similar, but package this in a function and one also has the ability to notify you when all the images have finished preloading.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
var imageList = new Array("dummyImg1.jpg", "dummyImg2.jpg");
var imagePlaceholder = new Array(imageList.length);
function waitImagesLoaded() {
var allImagesLoaded = true;
for (var i = 0; i < imageList.length && allImagesLoaded; i++) {
allImagesLoaded &= imagePlaceholder[i].complete;
}
if (allImagesLoaded) {
for (var i = 0; i < imageList.length; i++) {
var imgElemIdToReplace = "img" + String(i + 1);
replaceElem(imagePlaceholder[i], document.getElementById(imgElemIdToReplace));
}
} else {
window.setTimeout(waitImagesLoaded, 500);
}
}
function replaceElem(substituteElem, elemToReplace) {
var parentNode = elemToReplace.parentNode;
parentNode.replaceChild(substituteElem, elemToReplace);
}
</script>
</head>
<body>
<img id="img1" src="" alt="">
<img id="img2" src="" alt="">
<script type = "text/javascript">
for (var i = 0; i < imageList.length; i++) {
var imageObject = new Image();
imageObject.src = imageList[i];
imagePlaceholder[i] = imageObject;
}
window.setTimeout(waitImagesLoaded, 500);
</script>
</body>
</html>

Categories

Resources