I have HTML like this:
<div class="h5p-image">
<img src="localhost/images/file-5fa55a3d758c4.jpg" alt="New image" title="" style="width: 100%; height: 100%;">
</div>
and I want to select that image via src, so my JS looks like this:
var list= document.querySelectorAll('.h5p-image > img').src = "file-5fa55a3d758c4.jpg";
var i;
for (i = 0; i < list.length; i++) {
list[i].style.width = "300px";
}
Error from the console:
Uncaught TypeError: Cannot read property 'length'
Can anybody try to help me with this?
Your list is either
var list= document.querySelectorAll('.h5p-image > img')
OR
var list= document.querySelectorAll('.h5p-image > img[src$="5fa55a3d758c4.jpg"]') (using ends-with)
assuming you have more than one div with that image.
So the code is likely this to style the div
[...document.querySelectorAll('.h5p-image > img[src$="5fa55a3d758c4.jpg"]')]
.forEach(img => img.closest("div").style.width = "300px");
or this to just style the image
[...document.querySelectorAll('.h5p-image > img[src$="5fa55a3d758c4.jpg"]')]
.forEach(img => img.style.width = "300px");
Or if there is only ONE image
document.querySelector('.h5p-image > img').style.width = "300px"
[...document.querySelectorAll('.h5p-image > img[src$="758c4.jpg"]')]
.forEach(img => img.style.width = "300px");
<div class="h5p-image">
<img src="https://www.nice-premium.com/local/cache-vignettes/L600xH800/2012-03-19_08.53.13-758c4.jpg" alt="New image" title="" style="width: 100%; height: 100%;">
</div>
<div class="h5p-image">
<img src="https://www.nice-premium.com/local/cache-vignettes/L600xH800/2012-03-19_08.53.30-f371c.jpg" alt="New image" title="" style="width: 100%; height: 100%;">
</div>
<div class="h5p-image">
<img src="https://www.nice-premium.com/local/cache-vignettes/L600xH800/2012-03-19_08.53.13-758c4.jpg" alt="New image" title="" style="width: 100%; height: 100%;">
</div>
Related
I have a series of images with the class of .piece in a div called #pieces. Only the first image #piece0 is shown initially, and as you click on #piece0, #piece1 appears on top of #piece0. And then when you click on #piece1, #piece2 appears on top. My current code doesn't do that. How do I fix that?
<div id="pieces">
<img class="piece" id="piece0" style="display:block;"/>
<img class="piece" id="piece1" style="display:none;"/>
<img class="piece" id="piece2" style="display:none;"/>
<img class="piece" id="piece3" style="display:none;"/>
</div>
<script>
var pieceNum = $("#pieces").children().size();
var i = 0;
if (i < pieceNum) {
$("#piece" + i).click(function({
i++;
$("piece" + i).css("display", "block");
}));
}
</script>
If you want to get element children size(length) , use $("#pieces img").length . But for your problem that is not necessary .
You can catch image click by $("pieces img").on("click".. and get next element by .next() then the last element have no next , for that case you can check by next().length . 0 will return if next element have no exist
$("#pieces img").on("click",function() {
$(this).next().show();
$("#pieces").append($(this));
});
#pieces {
display: flex;
flex-direction: column;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="pieces">
<img class="piece" id="piece0" style="display:block;" alt="one"/>
<img class="piece" id="piece1" style="display:none;" alt="two"/>
<img class="piece" id="piece2" style="display:none;" alt="three"/>
<img class="piece" id="piece3" style="display:none;" alt="four"/>
</div>
$(document).ready(function(){
var pieceNum = $("#pieces").children();
var i = 0;
if (i < pieceNum.length) {
$("#piece" + i).click(function(){
$("#piece" + i).css("display", "none");
i++;
$("#piece" + i).css("display", "block");
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="pieces">
<img class="piece" id="piece0" style="display:block;" src="http://placekitten.com/g/200/300"/>
<img class="piece" id="piece1" style="display:none;" src="http://placekitten.com/g/200/400"/>
<img class="piece" id="piece2" style="display:none;" src="http://placekitten.com/g/200/300"/>
<img class="piece" id="piece3" style="display:none;" src="http://placekitten.com/g/200/100"/>
</div>
Try this:
var pieceNum = $("#pieces").children().size();
var i = 0;
if (i < pieceNum) {
$("#piece" + i).click(function({
$("piece" + i).css("display", "none");
i++;
$("piece" + i).css("display", "block");
}));
}
You don't need to write multiple click events, You can have single click event attached to all elements and do traversing using .next() to show next element :
$(".piece").click(function({
var $nextPiece = $(this).next();
if($nextPiece.length > 0)
$nextPiece.css("display", "block");
}));
You can use the next() to access next child and show() to display the img. Also, you will need to add position: absolute; to make images overlap each other.
$(document).ready(function() {
$('.piece').on('click', function() {
$(this).next().show();
});
});
img {
max-width: 100px;
margin-right: 1em;
position: absolute;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<div id="pieces">
<img class="piece" src="https://res.cloudinary.com/demo/image/upload/w_250,h_250,c_mfit/w_700/sample.jpg" />
<img class="piece" src="https://res.cloudinary.com/demo/image/upload/w_300,h_200,c_crop/sample.jpg" style="display:none;" />
<img class="piece" src="https://res.cloudinary.com/demo/image/upload/w_250,h_250,c_mfit/w_700/sample.jpg" style="display:none;" />
<img class="piece" src="https://res.cloudinary.com/demo/image/upload/w_300,h_200,c_crop/sample.jpg" style="display:none;" />
</div>
Try this
$(".piece").on('click', function(){
$(".piece").hide();
let id = (parseInt(this.id.slice(-1)) +1)%4;
$("#piece" +id).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="pieces">
<img class="piece" id="piece0" style="display:block;" alt="piece 0"/>
<img class="piece" id="piece1" style="display:none;" alt="piece 1"/>
<img class="piece" id="piece2" style="display:none;" alt="piece 2"/>
<img class="piece" id="piece3" style="display:none;" alt="piece 3"/>
</div>
How can I make the mainImage picture change places with the thumbnail and become the imgStyle picture?
I managed to move the thumbnail to the mainImage picture but I do not know what to do to move the main picture to the miniatures.
I'm happy for any advice.
var mini = document.getElementsByClassName('imgStyle');
for(var i = 0; i < mini.length; i++)
mini[i].addEventListener('click', function(e){
var imgUrl = this.src;
var mainUrl = document.getElementById('mainImage');
mainUrl.src = imgUrl;
});
.add_gallery{
width: 25%;
}
#mainImage{
width: 100%;
}
.miniatures{
width: 100%;
display: flex;
}
.imgStyle{
height: 100px;
}
<div class="add_gallery">
<div class="galery">
<img id="mainImage" src="https://thumbs.dreamstime.com/z/obsługuje-brać-obrazek-selfie-z-jego-smartphone-w-górach-zdjęcie-ruchomej-55632576.jpg" />
<br />
</div>
<div class="miniatures">
<img class="imgStyle" src="http://www.grhnarew.fora.pl/images/galleries/3876491244c9e14053175d-428229-wm.jpg">
<img class="imgStyle" src="http://sekretystronwww.pl/wp-content/uploads/2015/11/temat2015m_2.jpg">
<img class="imgStyle" src="http://www.bordercollie.fora.pl/images/galleries/1287702814bfa931698357-712854-wm.jpg">
<img class="imgStyle" src="https://img-ovh-cloud.zszywka.pl/0/0000/6629-cudowny-obrazek.jpg">
</div>
</div><!--add_gallery-->
You almost have it, just set the mini image that was clicked src to the main images src before you set it.
var mini = document.getElementsByClassName('imgStyle');
for(var i = 0; i < mini.length; i++)
mini[i].addEventListener('click', function(e){
var imgUrl = this.src;
var mainUrl = document.getElementById('mainImage');
this.src = mainUrl.src;
mainUrl.src = imgUrl;
});
.add_gallery{
width: 25%;
}
#mainImage{
width: 100%;
}
.miniatures{
width: 100%;
display: flex;
}
.imgStyle{
height: 100px;
}
<div class="add_gallery">
<div class="galery">
<img id="mainImage" src="https://thumbs.dreamstime.com/z/obsługuje-brać-obrazek-selfie-z-jego-smartphone-w-górach-zdjęcie-ruchomej-55632576.jpg" />
<br />
</div>
<div class="miniatures">
<img class="imgStyle" src="http://www.grhnarew.fora.pl/images/galleries/3876491244c9e14053175d-428229-wm.jpg">
<img class="imgStyle" src="http://sekretystronwww.pl/wp-content/uploads/2015/11/temat2015m_2.jpg">
<img class="imgStyle" src="http://www.bordercollie.fora.pl/images/galleries/1287702814bfa931698357-712854-wm.jpg">
<img class="imgStyle" src="https://img-ovh-cloud.zszywka.pl/0/0000/6629-cudowny-obrazek.jpg">
</div>
</div>
I'm trying to make a slider by adding 100% to each image but can not get it done.
My main question is how to add the percentages. I tried console.log(100% + 100%) just for an example and it does not work either. Thanks for any suggestions.
<section class="slider">
<img class="img" id="img1" src="girl.jpg" alt="" style="left: -100%">
<img class="img" id="img2" src="sport.jpg" alt="" style="left: 200%" >
<img class="img" id="img3" src="biceps.jpg" alt="" style="left: 100%" >
<img class="img" id="img4" src="weights.jpg" alt="" style="left: 0%">
</section>
javascript
var img = document.getElementsByClassName('img');
function slide() {
for(i=0; i < img.length; i++) {
img[i].style.left += "100%";
console.log(img[i].style.left);
}
}
You can't because this attribute's value is not a number (it's a text). So here's what you can do:
Try to parse the text to get only the number portion, parse it into an integer, do the math, then turn it back to a string. Something like
let tempPercent = parseInt(img[i].style.left.replace('%', ''), 10);
tempPercent += 100;
img[i].style.left = tempPercent+'%';
Beginner here.
I have a small image gallery, with two classes declared in CSS:
imagem: selected image, with border
imagem-activa: all the others, without border
How can i use JavaScript to add/remove the classes when the user clicks one image? I already know how to do it in jQuery, but want to learn also pure JS.
HTML
<div class="exercicio">
<h2 class="titulo">
Exercício 4
</h2>
<img src="img/imagem1.jpg" class="imagem imagem-activa" />
<img src="img/imagem2.jpg" class="imagem" />
<img src="img/imagem3.jpg" class="imagem" />
<img src="img/imagem4.jpg" class="imagem" />
</div>
CSS
.imagem{border:5px solid #000;opacity:0.5;cursor: pointer;}
.imagem-activa{border:5px solid #ff0066;opacity:1;}
JS
This part i can't make it work. Can someone help me?
var imagens = document.getElementsByClassName("imagem");
var imagemActual = 0;
for(var i = 0; i < imagens.length; i++) {
imagens[i].addEventListener("click", function() {
imagens[imagemActual].classList.remove("imagem-activa");
this.classList.add("imagem-activa");
imagemActual = i;
});
}
This is my working jQuery solution
$(".imagem").click(function() {
$(".imagem").removeClass("imagem-activa");
$(this).addClass("imagem-activa");
});
So, what is happening here is that anytime any of your click handlers is invoked, your variable imageActual gets set to the current value of i which will always be 4 because this is the final value of i after the for loop. For the first click, you might not run into any errors and you might get the expected result. But as soon as any of your event listeners has run, the value of imagemActual will be 4 and that will cause an error on any future invocation of your event listeners because imagens[4] will be undefined.
There are a few ways to solve this.
1) bind
You can bind the (temporary) value of i inside the loop to the event listener function:
var imagens = document.getElementsByClassName("imagem");
var imagemActual = 0;
for(var i = 0; i < imagens.length; i++) {
imagens[i].addEventListener("click", function(index) {
imagens[imagemActual].classList.remove("imagem-activa");
this.classList.add("imagem-activa");
imagemActual = index;
}.bind(imagens[i], i));
}
.imagem {
width: 20px;
height: 20px;
background-color: blue;
}
.imagem.imagem-activa {
background-color: red;
}
<div class="exercicio">
<h2 class="titulo">
Exercício 4
</h2>
<img src="" class="imagem imagem-activa" />
<img src="" class="imagem" />
<img src="" class="imagem" />
<img src="" class="imagem" />
</div>
2) let
If you can use ES6, you can use let which will make sure that your counting variable is a unique instance for every value that is applied:
const imagens = document.getElementsByClassName("imagem");
let imagemActual = 0;
for(let i = 0; i < imagens.length; i++) {
imagens[i].addEventListener("click", function() {
imagens[imagemActual].classList.remove("imagem-activa");
this.classList.add("imagem-activa");
imagemActual = i;
});
}
.imagem {
width: 20px;
height: 20px;
background-color: blue;
}
.imagem.imagem-activa {
background-color: red;
}
<div class="exercicio">
<h2 class="titulo">
Exercício 4
</h2>
<img src="" class="imagem imagem-activa" />
<img src="" class="imagem" />
<img src="" class="imagem" />
<img src="" class="imagem" />
</div>
I'm making a really simple photo gallery with thumbnails and I have a working code which changes the big image when a thumbnail is clicked. Now what I need is to add a green border to the thumbnail which is currently active.
HTML:
<div id="gallery">
<div id="big">
<img align="center" src="big/pipe_big.jpg" alt="" id="image" />
</div>
<div id="small">
<img onclick="changeImage('pipe')" src="small/pipe_small.jpg" alt="" />
<img onclick="changeImage('leaves')" src="small/leaves_small.jpg" alt="" />
<img onclick="changeImage('orange')" src="small/orange_small.jpg" alt="" />
<img onclick="changeImage('xuangong')" src="small/xuangong_small.jpg" alt="" />
</div>
<div id="small">
<img onclick="changeImage('grave')" src="small/grave_small.jpg" alt="" />
<img onclick="changeImage('lotus')" src="small/lotus_small.jpg" alt="" />
<img onclick="changeImage('tibet_girl')" src="small/tibet_girl_small.jpg" alt="" />
<img onclick="changeImage('girl_water')" src="small/girl_water_small.jpg" alt="" />
</div>
</div>
JS:
function changeImage(x){
var image = document.getElementById('image');
var active_image = ??????????
if (x == 'pipe') {
image.src = 'big/pipe_big.jpg';
} else if (x == 'leaves') {
image.src = 'big/leaves_big.jpg';
} else if (x == 'orange') {
image.src = 'big/orange_big.jpg';
} else if (x == 'xuangong') {
image.src = 'big/xuangong_big.jpg';
} else if (x == 'grave') {
image.src = 'big/grave_big.jpg';
} else if (x == 'lotus') {
image.src = 'big/lotus_big.jpg';
} else if (x == 'tibet_girl') {
image.src = 'big/tibet_girl_big.jpg';
} else if (x == 'girl_water') {
image.src = 'big/girl_water_big.jpg';
}
active_image.style.border = '2px solid green';
}
So I need to find the element that triggered the function and put it into variable "active_image" so that the function "changeImage()" always changes the border to 2px solid green. And please no jQuery solutions, I need it to be JavaScript.
Are you looking for this?
var images = document.querySelectorAll( "#gallery img" );
for( i =0; i< images.length; i++ ) {
images[i].style.border = "0px";
}
var active_image = event.target;
Just change the function calls to include 'this' as the second parameter:
<div id="gallery">
<div id="big">
<img align="center" src="big/pipe_big.jpg" alt="" id="image" />
</div>
<div id="small">
<img id="img1" onclick="changeImage('pipe',this)" src="small/pipe_small.jpg" alt="" />
<img id="img2" onclick="changeImage('leaves',this)" src="small/leaves_small.jpg" alt="" />
<img id="img3" onclick="changeImage('orange',this)" src="small/orange_small.jpg" alt="" />
<img id="img4" onclick="changeImage('xuangong',this)" src="small/xuangong_small.jpg" alt="" />
</div>
<div id="small">
<img id="img5" onclick="changeImage('grave',this)" src="small/grave_small.jpg" alt="" />
<img id="img6" onclick="changeImage('lotus',this)" src="small/lotus_small.jpg" alt="" />
<img id="img7" onclick="changeImage('tibet_girl',this)" src="small/tibet_girl_small.jpg" alt="" />
<img id="img8" onclick="changeImage('girl_water',this)" src="small/girl_water_small.jpg" alt="" />
</div>
And the dom element will be available in the function. So your function becomes:
var active_element_id;
function changeImage(x,element){
var image = document.getElementById('image');
var active_image = element.src;
if (x == 'pipe') {
image.src = 'big/pipe_big.jpg';
} else if (x == 'leaves') {
image.src = 'big/leaves_big.jpg';
} else if (x == 'orange') {
image.src = 'big/orange_big.jpg';
} else if (x == 'xuangong') {
image.src = 'big/xuangong_big.jpg';
} else if (x == 'grave') {
image.src = 'big/grave_big.jpg';
} else if (x == 'lotus') {
image.src = 'big/lotus_big.jpg';
} else if (x == 'tibet_girl') {
image.src = 'big/tibet_girl_big.jpg';
} else if (x == 'girl_water') {
image.src = 'big/girl_water_big.jpg';
}
if(active_element_id){
var active_element = document.getElementById(active_element_id);
active_element.style.border = '0px solid green';
}
element.style.border = '2px solid green';
active_element_id = element.getAttribute('id');
}
You can add a green border to the element which is currently being hovered over, by using onmouseover and onmouseout as well as this.style.borderColor to change the color:
<img onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'" onclick="changeImage('pipe')" src="small/pipe_small.jpg" alt="" />
Working Example:
div {
border-style: solid;
border-width: medium;
border-color: black;
width: 100px;
height: 100px;
}
<div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br>
<div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br><div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br><div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br><div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br><div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br><div onmouseover="this.style.borderColor='green'" onmouseout="this.style.borderColor='black'"></div><br>
Plunkr Example
The way with least changes to your code:
function changeImage(x){
var active_image = this;
var image = document.getElementById('image');
var images = [],
containers = document.getElementsByClassName('small');
for (var i=0,n=containers.length; i < n; i++){
var imgs = containers[i].getElementsByTagName('img');
for (var j=0,m=imgs.length; j < m; j++ ){
images = images.concat(imgs[j]);
}
}
if (x == 'pipe') {
image.src = 'big/pipe_big.jpg';
} else if (x == 'leaves') {
image.src = 'big/leaves_big.jpg';
} else if (x == 'orange') {
image.src = 'big/orange_big.jpg';
} else if (x == 'xuangong') {
image.src = 'big/xuangong_big.jpg';
} else if (x == 'grave') {
image.src = 'big/grave_big.jpg';
} else if (x == 'lotus') {
image.src = 'big/lotus_big.jpg';
} else if (x == 'tibet_girl') {
image.src = 'big/tibet_girl_big.jpg';
} else if (x == 'girl_water') {
image.src = 'big/girl_water_big.jpg';
}
// reset border
for (var i=0,n=images.length;i<n;i++){
images[i].style.border = '0px solid green';
}
// set active border
active_image.style.border = '2px solid green';
}
Note you cannot have two elements with the same ID (e.g., small), so you must use a class, or change the ID to a unique name.
Also see that if you use the call() method, you can pass along what this is. In this case, it's important because you want to pass along the element that is being clicked. So for onclick="<function name>.call(this)", the this is that element.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div id="gallery">
<div id="big">
<img align="center" src="big/pipe_big.jpg" alt="" id="image" />
</div>
<div class="small">
<img onclick="changeImage.call(this,'pipe')" src="small/pipe_small.jpg" alt="" />
<img onclick="changeImage.call(this,'leaves')" src="small/leaves_small.jpg" alt="" />
<img onclick="changeImage.call(this,'orange')" src="small/orange_small.jpg" alt="" />
<img onclick="changeImage.call(this,'xuangong')" src="small/xuangong_small.jpg" alt="" />
</div>
<div class="small">
<img onclick="changeImage.call(this,'grave')" src="small/grave_small.jpg" alt="" />
<img onclick="changeImage.call(this,'lotus')" src="small/lotus_small.jpg" alt="" />
<img onclick="changeImage.call(this,'tibet_girl')" src="small/tibet_girl_small.jpg" alt="" />
<img onclick="changeImage.call(this,'girl_water')" src="small/girl_water_small.jpg" alt="" />
</div>
</div>
</body>
</html>
Big Note
There is much more you could do to your code to make it more scalable and efficient, this is only a starter answer, without confusing you too much. Please keep at, keep learning and expanding your knowledge.
You can use this inside an event handler to get the element. However, since you use inline event handlers, inside changeImage, this will be another value (you could still pass it using call, apply, or as an argument).
However, better avoid inline event listeners:
var image = document.getElementById('image'),
images = document.getElementById('small').getElementsByTagName('img');
for(var i=0; i<images.length; ++i)
images[i].addEventListener('click', changeImage);
function changeImage(){
var x = this.getAttribute('data-img');
image.src = 'big/' + x + '_big.jpg';
this.style.border = '2px solid green';
}
<div id="gallery">
<div id="big">
<img align="center" src="big/pipe_big.jpg" alt="" id="image" />
</div>
<div id="small">
<img data-img="pipe" src="small/pipe_small.jpg" alt="" />
<img data-img="leaves" src="small/leaves_small.jpg" alt="" />
<img data-img="orange" src="small/orange_small.jpg" alt="" />
<img data-img="xuangong" src="small/xuangong_small.jpg" alt="" />
<img data-img="grave" src="small/grave_small.jpg" alt="" />
<img data-img="lotus" src="small/lotus_small.jpg" alt="" />
<img data-img="tibet_girl" src="small/tibet_girl_small.jpg" alt="" />
<img data-img="girl_water" src="small/girl_water_small.jpg" alt="" />
</div>
</div>