Resizing 3 images with javascript - javascript

I need to resize 3 images with javascript. How can i do that without having an ID and without having possibility to add one?
I have tried this but i don t know how to select all images(i need to set the width to 50px).
let images=document.querySelector('img');
images.setAttribute("width",50);

Is document.querySelectorAll() what you're looking for? document.querySelectorAll() will select all elements matching a certain selector, not just the first.
In your case, it might be
let images=document.querySelectorAll('img');
images.forEach(img => img.setAttribute("width",50));

If you can't use CSS to change the image width pick up the images with querySelectorAll and then iterate over the node list of images and change the width of each one.
const images = document.querySelectorAll('img');
images.forEach(image => image.setAttribute('width', '50px'));
<img src="https://dummyimage.com/100x100/000/fff" />
<img src="https://dummyimage.com/100x100/000/fff" />
<img src="https://dummyimage.com/100x100/000/fff" />

You can do it with querySelectorAll
changeSize = () => {
let images = document.querySelectorAll('img');
for (let i = 0; i < images.length; i++) {
images[i].style.width = "100px";
}
}
originSize = () => {
let images = document.querySelectorAll('img');
for (let i = 0; i < images.length; i++) {
images[i].removeAttribute("style");
}
}
.images {
display: flex;
}
.images img {
margin: 1em 1em 0 0;
}
<button onclick="changeSize()">Change Size</button>
<button onclick="originSize()">Origin Size</button>
<div class='images'>
<img src="https://cdnp2.stackassets.com/b1284961a6fbcbcfabe6f69c2ae4219ff6daa5e0/store/opt/596/298/1ca89e578fc4e326fe08196758c1688929acc8c5eeb8572e2282628cad78/product_30565_product_shot_wide.jpg" />
<img src="https://cdnp2.stackassets.com/b1284961a6fbcbcfabe6f69c2ae4219ff6daa5e0/store/opt/596/298/1ca89e578fc4e326fe08196758c1688929acc8c5eeb8572e2282628cad78/product_30565_product_shot_wide.jpg" />
<img src="https://cdnp2.stackassets.com/b1284961a6fbcbcfabe6f69c2ae4219ff6daa5e0/store/opt/596/298/1ca89e578fc4e326fe08196758c1688929acc8c5eeb8572e2282628cad78/product_30565_product_shot_wide.jpg" />
</div>

Related

How can I make a style event with addEventListener to multiple Nodes

I am trying to set a style event for a multiple images tags and I can't: the error is in the anonymous function of the event when I put into a loop to make the effect individually and for all galleries in the document with images[i].
Why ? : Uncaught TypeError: Cannot set property 'style' of undefined at HTMLImageElement.<anonymous>
images = document.querySelectorAll(".gallery img");
for (var i=0; i<images.length; i++){
images[i].addEventListener('mouseout', function(){ images[i].style=" transform: scale(.8)" });
images[i].addEventListener('mouseover', function(){ images[i].style=" transform: scale(1.2)" });
}
<div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>
ES6+ solution:
Simply change var to let in the for loop.
images = document.querySelectorAll(".gallery img");
for (let i = 0; i < images.length; i++){
images[i].addEventListener('mouseout', function(){ images[i].style=" transform: scale(.8)" });
images[i].addEventListener('mouseover', function(){ images[i].style=" transform: scale(1.2)" });
}
<div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>
If you must use var rather than let, you can use .bind() to set the value of i for the function. Otherwise it will reference the last value of i in the loop because of the async nature of the event callback and the higher scope of i due to the use of var.
images = document.querySelectorAll(".gallery img");
function callback1(i){ images[i].style=" transform: scale(.8)" };
function callback2(i){images[i].style=" transform: scale(1.2)" };
for (var i=0; i<images.length; i++){
images[i].addEventListener('mouseout', callback1.bind(this, i));
images[i].addEventListener('mouseover', callback2.bind(this, i));
}
<div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>
You should essentially never use var in Javascript but use let instead. var has weird scoping rules and should be removed from the language, the only reason it's still there is backwards compatibility.
But you should just always use let (or const) and it will work as expected.
Use arrow functions in callback for events to have right context (this)
images = document.querySelectorAll(".gallery img");
images.forEach((img) => {
img.addEventListener("mouseout", () => {
img.style = " transform: scale(.8)";
});
img.addEventListener("mouseover", () => {
img.style = " transform: scale(1.2)";
});
});
<div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>
Use forEach instead of a for loop:
images.forEach(i=> {
i.addEventListener('mouseout', function() { i.style=" transform: scale(.8)" });
i.addEventListener('mouseover', function() { i.style=" transform: scale(1.2)" });
})

Not able to append a paragraph to the image element

I made this favImages array and added some image objects to it. Then I am trying to append a paragraph element(removeButton) to each of them which will be triggered by clicking the images.
var favImages = new Object();
for (var i = 0; i < 5; i++) {
favImages[i] = document.getElementById("fav" + (i + 1));
}
var removeButton = document.createElement("p");
removeButton.id = "removebutton";
removeButton.innerHTML = "Remove Image";
for (var i = 0; i < 5; i++) {
var newImage = document.getElementById(favImages[i].id);
newImage.addEventListener("click", function() {
newImage.appendChild(removeButton)
}, false);
}
Don't use a loop. Use an event listener on the container and test what was clicked using event.target. You cannot add a child to an image
You COULD use a div, put the image as a background and the span to click as content
Anyway here are some examples
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("remove")) tgt.closest("div").remove()
})
#container div {
width: 200px
}
.remove {
float: right
}
<div id="container">
<div>
<span class="remove">X</span>
<img src="https://via.placeholder.com/150/0000FF/000888?text=image1" />
</div>
<div>
<span class="remove">X</span>
<img src="https://via.placeholder.com/150/FF00FF/000888?text=image2" />
</div>
<div>
<span class="remove">X</span>
<img src="https://via.placeholder.com/150/FF0000/000888?text=image3" />
</div>
</div>
From an array:
const images = [
"https://via.placeholder.com/150/0000FF/000888?text=image1",
"https://via.placeholder.com/150/FF00FF/000888?text=image2",
"https://via.placeholder.com/150/FF0000/000888?text=image3"
];
const container = document.getElementById("container");
container.innerHTML = images.map(img => `<div><span class="remove">X</span>
<img src="${img}" /></div>`).join("");
container.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("remove")) tgt.closest("div").remove()
})
#container div {
width: 200px
}
.remove {
float: right
}
<div id="container">
</div>

Using DOM to figure out how many images are on my page

I'm trying to use the DOM to find out how many images on are my page. I need to write code that will check my page to see how many images there are and store them to a variable. I'm not sure how to write this code but I know you need to search the code for all tags.
<body>
<div id="main_content">
<div id="image_selection">
<script type="text/javascript">
</script>
</div>
<div id="images">
<h3>Some Images</h3>
<p><img src="firetruck.jpg" > |
<img src="baseball.jpg" > |
<img src="soccer_ball.jpg" >
</p>
</div><!-- end of 'images' div -->
</div><!-- end of 'main content' div -->
var numberOfImgTags = document.getElementsByTagName('img').length
try this.
To find all the <img> elements on the page, and assign the resulting NodeList to a variable:
// (returns live HTMLCollection):
let allImages1 = document.images;
// or (returns (static, non-live) NodeList):
let allImages2 = document.querySelectorAll('img');
// or (returns (live) HTMLCollection):
let allImages3 = document.getElementsByTagName('img');
To find out how many <img> elements were found simply access the length property of the NodeList, for example:
let totalNumberOfImages = allImages1.length;
To demonstrate the difference between 'live' and 'static' collections:
Using: document.images:
let images = document.images,
counter = document.querySelector('.count');
counter.textContent = images.length;
Array.from(images).forEach(
(el) => {
el.addEventListener('click', (evt) => {
evt.target.remove();
counter.textContent = images.length;
});
})
body {
display: grid;
grid-template-columns: repeat(3, 200px);
}
span.count {
grid-column: 1 / -1;
background-color: limegreen;
text-align: center;
font-weight: bold;
}
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<span class="count"></span>
JS Fiddle demo.
Using document.querySelectorAll('img'):
let images = document.querySelectorAll('img'),
counter = document.querySelector('.count');
counter.textContent = images.length;
Array.from(images).forEach(
(el) => {
el.addEventListener('click', (evt) => {
evt.target.remove();
counter.textContent = images.length;
});
})
body {
display: grid;
grid-template-columns: repeat(3, 200px);
}
span.count {
grid-column: 1 / -1;
background-color: limegreen;
text-align: center;
font-weight: bold;
}
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<span class="count"></span>
JS Fiddle demo.
Using document.getElementsByTagName('img'):
let images = document.getElementsByTagName('img'),
counter = document.querySelector('.count');
counter.textContent = images.length;
Array.from(images).forEach(
(el) => {
el.addEventListener('click', (evt) => {
evt.target.remove();
counter.textContent = images.length;
});
})
body {
display: grid;
grid-template-columns: repeat(3, 200px);
}
span.count {
grid-column: 1 / -1;
background-color: limegreen;
text-align: center;
font-weight: bold;
}
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<img src="https://placekitten.com/200/200" />
<span class="count"></span>
JS Fiddle demo.
Note that we (attempt to) update the count in the same way in each demo, simply accessing the length property of the images variable; the variable is updated, and is therefore 'live,' when using document.images and document.getElementsByTagName(), but it remains unchanged, and therefore 'static,' when using document.querySelectorAll():
References:
document.getElementsByTagName().
document.images.
document.querySelectorAll().
HTMLCollection.
jQuery will return a collection of elements that match a selector. That's all you need to just count: $('img').length
That's how your current code works:
$('img').attr('height','50px').attr('width','50px');
This will run an implicit loop over the elements of the collection and set its attributes.
$('img').length will give you total count that exist at the time you run it

Javascript Picture Slideshow

I'm using the basic code shown on https://www.w3schools.com/w3css/w3css_slideshow.asp to create an automatic slideshow for a website. Everything seems to be the same and for some reason, the slideshow is not working.
HTML:
<article id="elements">
<h2 class="major">Pictures</h2>
<div class="slideshow">
<script src="assets/slideshow.js"></script>
<img id="slide" src="images/colin1.jpg" style="width:75%">
<img id="slide" src="images/luke.jpg" style="width:75%">
<img id="slide" src="images/shep.jpg" style="width:75%">
</div>
CSS:
body #elements .slideshow #slide {
display: none;
}
JS:
var index = 0;
slideshow();
function slideshow() {
var i, x;
x = document.getElementById("slide");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
index++;
if (index > x.length) {
index = 1;
}
x[index-1].style.display = "block";
setTimeout(slideshow, 2000);
}
I appreciate anyone's help, and any ideas!
Agree with Gordon.
When selecting by ID only one element will be selected.
If you switch to using classes. e.g.
<img class="slide" src="images/colin1.jpg" style="width:75%">
Then you can select all the images using.
x = document.querySelectorAll(".slide");
which will return a nodeList, a similar construction to an Array but with different methods; that can be accessed via index. x[0], x[1], x[2].
hope this helps.
getElementById only returns one item, not an array, so you cannot use it to get all slides, use getElementsByClassName (https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName), and change id for classes:
var index = 0;
slideshow();
function slideshow() {
var i, x;
x = document.getElementsByClassName("slide");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
index++;
if (index > x.length) {
index = 1;
}
x[index - 1].style.display = "block";
setTimeout(slideshow, 2000);
console.log('changed image')
}
#elements .slideshow #slide {
display: none;
}
<article id="elements">
<h2 class="major">Pictures</h2>
<div class="slideshow">
<script src="assets/slideshow.js"></script>
<img class="slide" src="images/colin1.jpg" style="width:75%">
<img class="slide" src="images/luke.jpg" style="width:75%">
<img class="slide" src="images/shep.jpg" style="width:75%">
</div>
</article>

How can I add a link around every image on a page?

I want to add a link to all images on the page. The link should point to the image source.
For example, from this:
<img src="foo.jpg">
I want to get this:
<img src="foo.jpg">
I tried to do it like the following but nothing seems to happen. Do I then have to somehow add the new "a" element somewhere?
var images = document.getElementsByTagName('img');
for (var image in images) {
var a = document.createElement('a');
a.href = image.src;
a.innerHtml = image;
}
You are iterating over the indices (0, 1, 2, ...) of images in this line:
for (var image in images) {
If image were an HTML element, this line still wouldn't work because the innerHTML property expects HTML text, not an object:
a.innerHtml = image;
Finally, you have neglected to add the anchor to the document.
Here is a correct way to do it:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; ++i) {
var img = images[i];
var a = document.createElement('a'); // Make a new anchor.
a.href = img.src; // Point it at the image source.
img.parentNode.replaceChild(a, img); // Replace the image with the anchor.
a.appendChild(img); // Make the image a child of the anchor.
}
<img src="http://i.stack.imgur.com/bcOyt.png">
<img src="http://i.stack.imgur.com/IPkNZ.png">
<img src="http://i.stack.imgur.com/Kd7GM.png">
You just create the Tag, but not insert it to the Document.
You can use replaceChild method in Node to replace the Img tag.
May I suggest jQuery?
The following example won't work in the sandbox because of browser restrictions, but should work on a site that you control. Also, depending on circumstances, the browser might block the popup. But, in the case of links within the webpage own domain, this might be the better solution, because you avoid manipulating the DOM.
$(function () {
$('img').on('click', function () {
var win = window.open($(this).attr('src'), '_blank')
win.focus()
})
})
img {
border: 1px solid blue;
cursor: pointer;
float: left;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
Here is another approach, wrapping all the images in an a tag as you originally requested:
$(function () {
$('img').wrap(function () {
return ''
})
})
img {
border: 1px solid blue;
cursor: pointer;
float: left;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x100">
for each loops are somewhat strange in javascript, you need to access objects like this:
for (var image in images) {
var a = document.createElement('a');
a.href = images[image].src;
a.innerHtml = images[image];
a.appendChild(images[image]);
// then of course you need to replace the img with the anchor containing the image
images[image].parentNode.replaceChild(a, images[image]);
}
Generally speaking:
for(var obj in list) {
var current = list[obj];
}

Categories

Resources