JavaScript file name selector application, only selecting first element.
There are twelve images with a class of foto, each labelled step1.png, step2.png etc. When one of the images is clicked, the name of the image file should be displayed, less the png file extension. For example, step1.png become step1. It all works as expected but only ever displays the first file name no matter which image is clicked on. I would be very grateful for any clues to my error with this code.
<title>Photo Files</title>
<style>
.box {
margin: auto;
width: 200px;
background-color: lightgray;
}
.box p {
color: green;
font-weight: bold;
}
</style>
</head>
<body>
<h1>Selects image file name</h1>
<div class="box">
<img class="foto" src="images/step1.png" alt="" />
<img class="foto" src="images/step2.png" alt="" />
<img class="foto" src="images/step3.png" alt="" />
<img class="foto" src="images/step4.png" alt="" />
<img class="foto" src="images/step5.png" alt="" />
<img class="foto" src="images/step6.png" alt="" />
<img class="foto" src="images/step7.png" alt="" />
<img class="foto" src="images/step8.png" alt="" />
<img class="foto" src="images/step9.png" alt="" />
<img class="foto" src="images/step10.png" alt="" />
<img class="foto" src="images/step11.png" alt="" />
<img class="foto" src="images/step12.png" alt="" />
<p class="picName">Name of file:</p>
<br />
<hr />
</div>
<script>
var pic = document.querySelectorAll(".foto");
for (var i = 0; i < pic.length; i++) {
pic[i].addEventListener(
"click",
function () {
var fullPath = document.querySelector(".foto").src;
var filename = fullPath.replace(/^.*[\\\/]/, "");
document.querySelector(".picName").textContent =
"File name:" + filename.substring(0, filename.lastIndexOf(".")) ||
filename;
},
false
);
}
</script>
</body>
</html>
your issue come from the line
var fullPath = document.querySelector(".foto").src
that return only the first element that match selector .foto
to solve your issue recover image clicked by :
pass an event parameter to your function
recover target clicked with var target = e.target || e.srcElement;
but instead have 12 eventListeners it's better to have only one on parent element of all your clicked image (in your sample .box but you can create a parent one box-pic in my below sample)
var box = document.querySelector(".box-pic");
box.addEventListener('click', function(e) {
var target = e.target || e.srcElement;
if (target.src) {
var filename = target.src.replace(/^.*[\\\/]/, "");
document.querySelector(".picName").textContent = "File name:" + filename.substring(0, filename.lastIndexOf(".")) ||
filename;
}
});
.box {
margin: auto;
width: 200px;
background-color: lightgray;
}
.box p {
color: green;
font-weight: bold;
}
<h1>Selects image file name</h1>
<div class="box">
<div class="box-pic">
<img class="foto" src="images/step1.png" alt="img1" />
<img class="foto" src="images/step2.png" alt="img2" />
<img class="foto" src="images/step3.png" alt="img3" />
<img class="foto" src="images/step4.png" alt="img4" />
<img class="foto" src="images/step5.png" alt="img5" />
<img class="foto" src="images/step6.png" alt="img6" />
<img class="foto" src="images/step7.png" alt="img7" />
<img class="foto" src="images/step8.png" alt="img8" />
<img class="foto" src="images/step9.png" alt="img9" />
<img class="foto" src="images/step10.png" alt="img10" />
<img class="foto" src="images/step11.png" alt="img11" />
<img class="foto" src="images/step12.png" alt="img12" />
</div>
<p class="picName">Name of file:</p>
<br />
<hr />
</div>
Related
I have 4 image slideshows, and I am having trouble with the Javascript. I have given the div both an id and a class name. The class imageContainer is used in the CSS. Therefore I am using id for the Javascript, but it won't work. I can do this with one image slideshow, but I need to have multiple slideshows on the same page.
The HTML code below is not my actual code, it is just placeholder code I wrote to show what I want to achieve. The Javascript code, however, is my actual code.
I appreciate the help.
function openWin(url) {
aWindow = window.open(url, "Window 1", "width=400, height=400");
}
var numslides = 0,
currentslide = 0;
var slides = new Array();
function MakeSlideShow() {
container = document.getElementsById("Gallery");
for (i = 0; i < imgs.length; i++) {
if (imgs[i].className != "imga") continue;
slides[numslides] = imgs[i];
if (numslides == 0) {
imgs[i].style.display = "block";
} else {
imgs[i].style.display = "none";
}
imgs[i].onclick = NextSlide;
numslides++;
}
}
function NextSlide() {
slides[currentslide].style.display = "none";
currentslide++;
if (currentslide >= numslides) currentslide = 0;
slides[currentslide].style.display = "block";
}
window.onload = MakeSlideShow;
<h2>Gallery 1</h2>
<div id="Gallery" class="imageContainer">
<img class="img" src="https://via.placeholder.com/100" />
<img class="img" src="https://via.placeholder.com/101" />
<img class="img" src="https://via.placeholder.com/102" />
<img class="img" src="https://via.placeholder.com/103" />
</div>
<h2>Gallery 2</h2>
<div id="Gallery" class="imageContainer">
<img class="img" src="https://via.placeholder.com/106" />
<img class="img" src="https://via.placeholder.com/107" />
<img class="img" src="https://via.placeholder.com/108" />
<img class="img" src="https://via.placeholder.com/109" />
</div>
<h2>Gallery 3</h2>
<div id="Gallery" class="imageContainer">
<img class="img" src="https://via.placeholder.com/110" />
<img class="img" src="https://via.placeholder.com/111" />
<img class="img" src="https://via.placeholder.com/112" />
<img class="img" src="https://via.placeholder.com/113" />
</div>
<h2>Gallery 4</h2>
<div id="Gallery" class="imageContainer">
<img class="img" src="https://via.placeholder.com/114" />
<img class="img" src="https://via.placeholder.com/115" />
<img class="img" src="https://via.placeholder.com/116" />
<img class="img" src="https://via.placeholder.com/117" />
</div>
ID's must be unique, so, the best way to do this is get all galleries by their class name and start getting images from there. Note that slides is now a bidimensional array to hold gallery and images, something like:
slides[0] = [image100, image101, image102, image103];
I've added indexes for gallery and image to each picture using dataset propperty, so, you only need to know wich image was clicked instead of trying to get from currentslide. Also, numslides is provided from gallery length.
var slides = new Array();
function MakeSlideShow()
{
var containers = document.getElementsByClassName("imageContainer");
for(var x = 0; x < containers.length; x++) {
// Create gallery
slides[x] = new Array();
var imgs = containers[x].children;
for(var i = 0; i < imgs.length; i++) {
// Add image to current gallery
slides[x][i] = imgs[i];
// Set it's display, note that at least 1 images was added
if(slides[x].length == 1) {
imgs[i].style.display = 'block';
} else {
imgs[i].style.display = 'none';
}
// Add gallery and image info
imgs[i].dataset.gallery = x;
imgs[i].dataset.img = i;
// Add onclick event, but we need to send current image
imgs[i].onclick = function() {
nextSlide(this);
}
}
}
}
// This function needs to know wich img was clicked
function nextSlide(pic)
{
// Get gallery and image from dataset to know what to do
var gallery = pic.dataset.gallery;
var img = pic.dataset.img;
// Hide current image
slides[gallery][img].style.display = 'none';
// Search for next
img ++;
// No more images availabel, go to first
if(img == slides[gallery].length) {
img = 0;
}
// Show next image
slides[gallery][img].style.display = 'block';
}
window.onload = MakeSlideShow;
<h2>Gallery 1</h2>
<div id="Gallery1" class="imageContainer">
<img class="img" src="https://via.placeholder.com/100" />
<img class="img" src="https://via.placeholder.com/101" />
<img class="img" src="https://via.placeholder.com/102" />
<img class="img" src="https://via.placeholder.com/103" />
</div>
<h2>Gallery 2</h2>
<div id="Gallery2" class="imageContainer">
<img class="img" src="https://via.placeholder.com/106" />
<img class="img" src="https://via.placeholder.com/107" />
<img class="img" src="https://via.placeholder.com/108" />
<img class="img" src="https://via.placeholder.com/109" />
</div>
<h2>Gallery 3</h2>
<div id="Gallery3" class="imageContainer">
<img class="img" src="https://via.placeholder.com/110" />
<img class="img" src="https://via.placeholder.com/111" />
<img class="img" src="https://via.placeholder.com/112" />
<img class="img" src="https://via.placeholder.com/113" />
</div>
<h2>Gallery 4</h2>
<div id="Gallery4" class="imageContainer">
<img class="img" src="https://via.placeholder.com/114" />
<img class="img" src="https://via.placeholder.com/115" />
<img class="img" src="https://via.placeholder.com/116" />
<img class="img" src="https://via.placeholder.com/117" />
</div>
Im curently creating a picture gallery for my project in school. I came across the problem that i don't know how to add a picture description that will only show under the big preview picture and not next to the small pictures at the top. Every small picture will have a different description. I tried some stuff myself but i failed miserably, Im still new to all of this :)
Any solutions to that problem?
<head>
<title>Gallery</title>
<link href="galery.css" rel="stylesheet" type="text/css">
</head>
<body background="cosmic.jpg">
<div class="gallery" align="center">
<div class="smallpics">
<img onclick="getElementById('bigpic').src=this.src" id="picture1" src="images/picture1.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture2" src="images/picture2.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture3" src="images/picture3.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture4" src="images/picture4.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture5" src="images/picture5.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture6" src="images/picture6.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture7" src="images/picture7.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture8" src="images/picture8.png" />
<img onclick="getElementById('bigpic').src=this.src" id="picture9" src="images/picture9.png" />
</div>
<div class="bigpic" align="center">
<img id="bigpic" src="images/picture1.png" alt="" />
</div>
<div class="smallpics">
<img onclick="getElementById('bigpic').src=this.src; getElementById('bigpicDesc').innerHTML(this.alt) " id="picture1" src="images/picture1.png" alt="The Description" />
....
</div>
<div class="bigpic" align="center">
<img id="bigpic" src="images/picture1.png" alt="" />
<div id="bigpicDesc"> </div>
</div>
or
<div class="smallpics">
<img onclick="showInBig(this)" id="picture1" src="images/picture1.png" alt="The Description" />
....
</div>
<div class="bigpic" align="center">
<img id="bigpic" src="images/picture1.png" alt="" />
<div id="bigpicDesc"> </div>
</div>
function showInBig(element){
document.getElementById('bigpic').setAttribute('src',element.getAttribute('src'));
document.getElementById('bigpicDesc').innerHTML(element.element.getAttribute('alt'));
}
Given that alt of the small images are the descriptions.
The first thing is to clean up your HTML and separate out the JavaScript. This has a number of benefits. It keeps your HTML and JS separate without muddying one with the other.
All of your onclick code can be handled thus:
var big_pic = document.querySelector('#bigpic');
document.querySelector('body').addEventListener('click', function(evt) {
if (!/^picture\d+$/.test(evt.target.id)) return;
big_pic.src = evt.target.src;
}, false);
Now, let's consider adding a description. The first question is, how are you going to store these, and in relation to the images?
An obvious solution is to store them in a data attribute on the pictures elements. So just as we read the src from the clicked pic's element, we'll read its description from the same source.
So our elements become:
<img id='picture1' src='some/src.jpg' data-descr='Picture description here' />
Then you're going to need a description placeholder in the big picture area, so add a paragraph.
Finally, change the above JS code to factor in the description also:
var
big_pic = document.querySelector('#bigpic'),
big_pic_descr = document.querySelector('.bigpic p');
document.querySelector('body').addEventListener('click', function(evt) {
if (!/^picture\d+$/.test(evt.target.id)) return;
big_pic.src = evt.target.src;
big_pic_descr.innerHTML = evt.target.getAttribute('data-descr');
}, false);
Could be done in 2 ways, first by making use of data- attribute (1)
jsFiddle 1
var pics = document.querySelectorAll('.smallpics img'),
bigPic = document.getElementById('bigpic'),
descP = document.getElementById('description');
for (var i = 0, ln = pics.length; i < ln; i++) {
// we pass each img with its src and data-desc attributes to the function.
var $this = pics[i];
theClickFunction($this, $this.getAttribute('src'), $this.getAttribute('data-desc'));
}
function theClickFunction($th, $src, $desc) {
$th.addEventListener('click', function() {
//on click we update the bigpic display and thedescription paragraph
bigPic.setAttribute('src', $src);
bigPic.style.display = 'block';
descP.innerHTML = $desc;
});
}
body { margin: 0; padding: 0; }
.smallpics img { width: 19%; cursor: pointer; }
#bigpic { display:none}
<div class="gallery" align="center">
<div class="smallpics">
<img id="pic1" src="//dummyimage.com/300x100?text=pic1" data-desc="description of picture 1" />
<img id="pic2" src="//dummyimage.com/300x100?text=pic2" data-desc="description of picture 2" />
<img id="pic3" src="//dummyimage.com/300x100?text=pic3" data-desc="description of picture 3" />
<img id="pic4" src="//dummyimage.com/300x100?text=pic4" data-desc="description of picture 4" />
<img id="pic5" src="//dummyimage.com/300x100?text=pic5" data-desc="description of picture 5" />
<img id="pic6" src="//dummyimage.com/300x100?text=pic6" data-desc="description of picture 6" />
<img id="pic7" src="//dummyimage.com/300x100?text=pic7" data-desc="description of picture 7" />
<img id="pic8" src="//dummyimage.com/300x100?text=pic8" data-desc="description of picture 8" />
<img id="pic9" src="//dummyimage.com/300x100?text=pic9" data-desc="description of picture 9" />
<img id="pic10" src="//dummyimage.com/300x100?text=pic10" data-desc="description of picture 10" />
</div>
<hr>
<div class="bigpic" align="center">
<img id="bigpic" src="images/picture1.png" alt="" />
<p id="description"></p>
</div>
The other way is by using some hidden element, I used <ul> with its lis here but it could be divs or p etc.., while this way adds extra markup to the page it suits better when you have HTML, styled and/or long descriptions rather than just normal text.
jsFiddle 2
var pics = document.querySelectorAll('.smallpics img'),
DescLis = document.querySelectorAll('#hiddenDescs li'),
bigPic = document.getElementById('bigpic'),
descP = document.getElementById('description');
for (var i = 0, ln = pics.length; i < ln; i++) {
// we pass each img with its src attribute.
var $this = pics[i];
theClickFunction($this, $this.getAttribute('src'), i);
}
function theClickFunction($th, $src, i) {
$th.addEventListener('click', function() {
//on click we update the bigpic display and thedescription paragraph
bigPic.setAttribute('src', $src);
bigPic.style.display = 'block';
// get the inner html of the corresponding li and inject it as innerHTML
// of the descreption p
descP.innerHTML = DescLis[i].innerHTML;
});
}
(1) Using alt attribute, as in #Thuin's answer, rather than data-* is better because: This attribute defines the alternative text describing the image. Users will see this text displayed if the image URL is wrong, the image is not in one of the supported formats, or if the image is not yet downloaded.
I'm learning to make image gallery and when i click on thumbnail, it does nothing. Bellow is my code, I'm trying for some tome to make it work, can I get some help ?
HTML :
<script src="galerijaSlika.js"></script>
<img id="glavnaSlika" src="Slike/infogamer_galerija/info1.jpg">
<div id="sveSlike" onClick="promjeniSliku(event)">
<img src="Slike/infogamer_galerija/info1.jpg">
<img src="Slike/infogamer_galerija/info2.jpg">
<img src="Slike/infogamer_galerija/info3.jpg">
<img src="Slike/infogamer_galerija/info4.jpg">
<img src="Slike/infogamer_galerija/info5.jpg">
<img src="Slike/infogamer_galerija/info6.jpg">
<img src="Slike/infogamer_galerija/info7.jpg">
<img src="Slike/infogamer_galerija/info8.jpg">
<img src="Slike/infogamer_galerija/info9.jpg">
<img src="Slike/infogamer_galerija/info10.jpg">
<img src="Slike/infogamer_galerija/info11.jpg">
<img src="Slike/infogamer_galerija/info12.jpg">
</div>
Javascript :
function promjeniSliku(event){
event = event || window.event;
var trazeniElement = event.target || event.srcElement;
if(trazeniElement == "IMG"){
document.getElementById("glavnaSlika").src = trazeniElement.getAttribute("src");
}
}
Your typo is:
if(trazeniElement == "IMG"){
The correct test must be:
if (trazeniElement.tagName == "IMG") {
For details see MDN
function promjeniSliku(event){
event = event || window.event;
var trazeniElement = event.target || event.srcElement;
if (trazeniElement.tagName == "IMG") {
document.getElementById("glavnaSlika").src = trazeniElement.getAttribute("src");
}
}
<img id="glavnaSlika" src="Slike/infogamer_galerija/info1.jpg">
<div id="sveSlike" onClick="promjeniSliku(event)">
<img src="Slike/infogamer_galerija/info1.jpg">
<img src="Slike/infogamer_galerija/info2.jpg">
<img src="Slike/infogamer_galerija/info3.jpg">
<img src="Slike/infogamer_galerija/info4.jpg">
<img src="Slike/infogamer_galerija/info5.jpg">
<img src="Slike/infogamer_galerija/info6.jpg">
<img src="Slike/infogamer_galerija/info7.jpg">
<img src="Slike/infogamer_galerija/info8.jpg">
<img src="Slike/infogamer_galerija/info9.jpg">
<img src="Slike/infogamer_galerija/info10.jpg">
<img src="Slike/infogamer_galerija/info11.jpg">
<img src="Slike/infogamer_galerija/info12.jpg">
</div>
I got this working. I had to change the images around, and to get a larger item in the galeria image I had to do a string replace, feel free to delete that part.
function promjeniSliku(event) {
var target = event.target;
if (target.tagName == 'IMG') {
var src = target.src.replace(/100/g, '500');
document.getElementById('glavnaSlika').src = src;
}
}
<img id="glavnaSlika" src="//lorempixel.com/500/500/cats/1">
<div id="sveSlike" onclick="promjeniSliku(event)">
<img src="//lorempixel.com/100/100/cats/1" alt="" />
<img src="//lorempixel.com/100/100/cats/2" alt="" />
<img src="//lorempixel.com/100/100/cats/3" alt="" />
<img src="//lorempixel.com/100/100/cats/4" alt="" />
<img src="//lorempixel.com/100/100/cats/5" alt="" />
<img src="//lorempixel.com/100/100/cats/6" alt="" />
<img src="//lorempixel.com/100/100/cats/7" alt="" />
<img src="//lorempixel.com/100/100/cats/8" alt="" />
<img src="//lorempixel.com/100/100/cats/9" alt="" />
<img src="//lorempixel.com/100/100/cats/10" alt="" />
<img src="//lorempixel.com/100/100/cats/11" alt="" />
<img src="//lorempixel.com/100/100/cats/12" alt="" />
</div>
I have the following code
<div id="slider">
<img src="images/p1.jpg" />
<img src="images/p2.jpg" />
<img src="images/p3.jpg" />
</div>
I want to add <a> before and after the image tag with jQuery. This would be the result:
<div id="slider">
<img src="images/p1.jpg" />
<img src="images/p2.jpg" />
<img src="images/p3.jpg" />
</div>
Edit: Details from comments
So far, I have tried like this:
<span class="phone"><img src="malsup.github.io/images/p1.jpg"></span>
<span class="phone"><img src="malsup.github.io/images/p2.jpg"></span>
<span class="phone"><img src="malsup.github.io/images/p3.jpg"></span>
<span class="phone"><img src="malsup.github.io/images/p4.jpg"></span>
i have add like
$('.phone').each(function() {
$(this).wrapInner('<a href="test.php" />');
});
Additional information from comments
I want to use a different url for each image, like:
<div id="slider">
<img src="images/p1.jpg" />
<img src="images/p2.jpg" />
<img src="images/p3.jpg" />
</div>
You can do it using the JQuery wrap() function like so:
var arr = ['https://www.google.com/', 'https://www.yahoo.com/', 'https://www.bing.com/'];
$("#slider img").each(function(index, value){
$(this).wrap("<a href='"+arr[index]+"'></a>");
});
Here is the JSFiddle demo
Use .wrap()
Wrap an HTML structure around each element in the set of matched elements.
Here you can store different url in custom attributes which can later be used to wrap element.
$('#slider img').wrap(function() {
return $('<a />', {
"href": $(this).data('url'),
"class" : "myClass"
});
})
.myClass {
border: 1px solid red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<img src="images/p1.jpg" data-url='facebook.com' />
<img src="images/p2.jpg" data-url='google.com' />
<img src="images/p3.jpg" data-url='example.com' />
</div>
I'm trying to use the existing href value as my target in manipulating the css. Unfortunately, I can't seem to make it work. I need a little assistance where did I go wrong.
$(function(){
$('.tab-items a').each(function(){
var target_ids = $(this).attr('href').toLowerCase();;
var target_image =$(target_ids).find('a:first img').attr('src');
$(this).css('background' 'url("'+ target_image +'")');
})
})
.tab-items a {
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
margin: 5px;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="tab-items">
<li>
Nature
People
Animals
</li>
</ul>
<div>
<div id="nature_231">
<img src="http://lorempixel.com/400/200/nature/1" alt="" />
<img src="http://lorempixel.com/400/200/nature/2" alt="" />
<img src="http://lorempixel.com/400/200/nature/3" alt="" />
</div>
<div id="#people_541">
<img src="http://lorempixel.com/400/200/people/1" alt="" />
<img src="http://lorempixel.com/400/200/people/2" alt="" />
<img src="http://lorempixel.com/400/200/people/3" alt="" />
</div>
<div id="#animals_961">
<img src="http://lorempixel.com/400/200/animals/1" alt="" />
<img src="http://lorempixel.com/400/200/animals/2" alt="" />
<img src="http://lorempixel.com/400/200/animals/3" alt="" />
</div>
</div>
See out put ,Working Fine
You are missing comma separator in argument to css()
$(function(){
$('.tab-items a').each(function(){
var target_ids = $(this).attr('href').toLowerCase();;
console.log(target_ids)
var target_image =$(target_ids).find('a:first img').attr('src');
console.log(target_image)
$(this).css('background', 'url("'+ target_image +'")');
})
})
.tab-items a {
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
margin: 5px;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="tab-items">
<li>
Nature
People
Animals
</li>
</ul>
<div>
<div id="nature_231">
<img src="http://lorempixel.com/400/200/nature/1" alt="" />
<img src="http://lorempixel.com/400/200/nature/2" alt="" />
<img src="http://lorempixel.com/400/200/nature/3" alt="" />
</div>
<div id="#people_541">
<img src="http://lorempixel.com/400/200/people/1" alt="" />
<img src="http://lorempixel.com/400/200/people/2" alt="" />
<img src="http://lorempixel.com/400/200/people/3" alt="" />
</div>
<div id="#animals_961">
<img src="http://lorempixel.com/400/200/animals/1" alt="" />
<img src="http://lorempixel.com/400/200/animals/2" alt="" />
<img src="http://lorempixel.com/400/200/animals/3" alt="" />
</div>
</div>
IDK about JQuery,
But in Javascript, I would just iterate through an array of 'a' tags searching for the proper href, like this, you could even make it a function to ID your href:
var matchHref = function(input) {
var a = document.getElementsByTagName('a'), href, target;
for(var i = 0, j = a.length; i < j; ++i) {
href = a[i].getAttribute('href');
if(href === input){
target = a[i];
}
}
return target;
}
Then you could just do this to call it:
matchHref('href-name').style.whatever-you-change;