How to do a simple image swap with JS? - javascript

I'm learning Javascript for my Intro to Programming Concepts class and I decided to make a simple photography portfolio site for my final project. I'm making the gallery now and I'm not sure how swap images.
This is what it looks like (cut off but you get the idea):
screenshot
This is the HTML:
<div id="gallery">
<div>
<img src="images/nature/1.jpg">
<br>
<div class="gallery">
<img src="images/nature/2.jpg">
<img src="images/nature/3.jpg">
<img src="images/nature/4.jpg">
<img src="images/nature/5.jpg">
<img src="images/wedding/1.jpg">
<img src="images/wedding/2.jpg">
<img src="images/wedding/3.jpg">
<img src="images/wedding/5.jpg">
<img src="images/wedding/4.jpg">
</div>
</div>
</div>
How do I make it so when you click an img from .gallery it swaps places with the first img (images/nature/1.jpg)?

The following should take whatever image is currently in the first image and swap it out with the one that is clicked:
var firstImage = document.getElementsByTagName('img')[0],
gallery = document.getElementsByClassName('gallery')[0];
gallery.addEventListener('click', function(e) {
var target = e.target;
if (target.tagName == "IMG") {
var newImage = target.src;
target.src = firstImage.src;
firstImage.src = newImage;
}
});
You can test it out here: https://jsfiddle.net/hxhe90qL/6/
After enough clicking around, however, the images will probably be all out of order. You could change it to only swap the first image by replacing the code inside the if statement to:
firstImage.src = target.src;

I think you mean when you click on swipe div, no matter what pic is showing in .gallery will be replaced by 1.jpg.
If that is the case, you can bind onclick event on .gallery, by getting event object, you can get access to the source dom element that triggers the event.
Then you can use javascript to change src attribute.
var gallery = document.querySelector('.gallery');
gallery.addEventListener('click', function(e) {
var targetImg = e.target;
targetImg.src = 'images/nature/1.jpg';
});

Related

How to tell if <img> has href attribute?

So I have a simple slideshow using JavaScript to fade images in and out, where all but one of the img elements do not have a href attribute. I would like to put the href attribute of the image into the href attribute of the caption (actually the img alt attribute) so that the text is clickable when the particular slide shows up, and becomes unclickable when the slide goes to the next one. I am very inexperienced in JS and cannot find any resources online to help me with this particular issue. Here is the part of my HTML file (called Finley.html) that is used, and my slideshow.js file.
<section>
<!-- Slideshow -->
<h2 id="caption">Car ride home! First time meeting each other.</h2>
<img id="slide" src="images/Finley/car_ride_home.jpg" alt="">
<div id="slides">
<img src="images/Finley/car_ride_home.jpg" alt="Car ride home! First time meeting each other.">
<img src="images/Finley/he_lay.jpg" alt="Handsome boy!">
<img src="images/Finley/awwww.jpg" alt="First photo together">
<img src="images/Finley/photogenic_af.jpg" alt="Papa, we made it to the community Instagram!" href="https://google.com" target="_blank">
<img src="images/Finley/first_vet.jpg" alt="First vet trip was successful">
<img src="images/Finley/blop.jpg" alt="blop.">
<img src="images/Finley/squishy_cheek.jpg" alt="Car rides make me sleepy">
<img src="images/Finley/first_beach.jpg" alt="First time at the beach and I got rocked by the waves">
<img src="images/Finley/sploot.jpg" alt="sploot.">
<img src="images/Finley/floopy_ears.jpg" alt="My family loves how floopy my ears are!">
<img src="images/Finley/daisy_gf.jpg" alt="Playing with my friend Daisy!">
</div>
</section>
slideshow.js:
$(document).ready(function() {
//declare variables
var nextSlide = $("#slides img:first-child");
var nextCaption;
var nextSlideSource;
// the function for running the slide show
var runSlideShow = function() {
// write the function
$("#caption").fadeOut(1000);
$("#slide").fadeOut(1000,
function() { //callback function
if (nextSlide.next().length == 0) {
nextSlide = $("#slides img:first-child");
} else {
nextSlide = nextSlide.next();
}
nextSlideSource = nextSlide.attr("src");
nextCaption = nextSlide.attr("alt");
if (nextCaption == "Papa, we made it to the community Instagram!") {
$("#caption").attr("href", nextSlide.attr("href"); $("#caption").attr("target", nextSlide.attr("target");
}
$("#slide").attr("src", nextSlideSource).fadeIn(1000); $("#caption").text(nextCaption).fadeIn(1000);
}
); //callback
}; //ready
// start slide show
var timer1 = setInterval(runSlideShow, 5000);
// here's one way to code this app without using the toggle event method
$("#slide").click(function() {
if (timer1 != null) {
clearInterval(timer1);
timer1 = null;
} else {
timer1 = setInterval(runSlideShow, 1000);
}
});
})
This code displays the caption as text above the image, and the image stays on screen for 5 seconds before fading to the next image. To clarify, I'd like the caption text that appears to become a hyperlink to Google (actual site censored) for the one picture when it is displayed, and then return to normal once the next picture comes up. I tried putting line 21-24 in to test for the caption and set the attribute, but those lines stop the slideshow from working (remove those lines to see how it should behave). Maybe it's something in the if statement in line 21, but I'm not sure how to proceed. Any help or tips would be appreciated!
You can do it either like this:
this.hasAttribute('href');
or
$(this).is('[href]');
More Info

Link or button sets a variable, then calls the script

I have a script that plays a video in a Modal when a thumbnail gets clicked. This only works with the first video mentioned in the html, so I'm trying to use js to grab the particular video whos thumbnail is clicked on.
I have set up a variable in the js called vidcode, and gave it a value of the first video's address (rLdpnu2dDUY) or whatever it's called. I then set up a value 'start' for the link part before, and 'end' for the link part after. Now I have "showVideo = start + vidcode + end" and then innerHTML = showVideo, which works no problems.
So far the injection part works. My problem now is passing the address of the clicked thumbnail into the vidcode variable to play the corresponding video. I have looked on SO, w3, and Google. I have 6 different tries and none work fully.
I can create a link which
- Sets the variable, but then does not call the script.
- Calls the script but does not pass on the variable.
- Click one thumb to set the variable then another thumb to call the script. That one will then work but it's an extra step. At least with this one I know that the variable is being set..
<!--== Standard button but requires var vidcode to be preset in the Modal script ==-->
<img src="https://img.youtube.com/vi/rLdpnu2dDUY/hqdefault.jpg">
<!--== Add onClick to trigger a mini-script which sets the var vidcode early ==-->
<script>function hDSansxhArU(){var vidcode = 'hDSansxhArU';}</script>
<!--== Adding the javascript directly to the link code, yet it does not trigger the Modal script ===-->
<!--== Adding the javascript directly to the link code, to trigger a mini-script, to then call the modal ===-->
<script>function buttt(){var vidcode = 'duBjWlIzpzQ'; modalviewer();}</script>
<!--== Use the video's code as an id, then calling that id immediately and setting it to var vidcode ==-->
<script>
document.getElementById('hDSansxhArU').onclick = function() {
var vidcode = 'hDSansxhArU';
modalviewer()
};
</script>
Spots are commented out when trying something else
function modalviewer(){ //This function usually isn't here
var start = '<iframe width="840" height="472" src="https://www.youtube.com/embed/';
var end = '" frameborder="0" encrypted-media></iframe>';
//var showVideo = start + vidcode + end;
// This part works fine when vidcode gets a value
document.getElementById("button").addEventListener("click", function() {
document.querySelector(".theVideo").innerHTML = showVideo;
document.querySelector(".bg-modal").style.display = "flex";
});
document.querySelector(".bg-modal").addEventListener("click", function() { //.bg-modal to make the surrounding clickable
document.querySelector(".bg-modal").style.display = "none";
document.querySelector(".theVideo").innerHTML = "";
});
};
Expected results:
Click a link and have either
- set that address to variable 'vidcode', or
- set the address gobbledegook to 'vidcode' from here
and either have the modal script in a separate js file or at the bottom of the page.
As a code-newbie, I'm proud to have figured it out so far (with previous help from SO), it just frustrates me that I can only get half of this to work at a time :/.
#CTOverton provided what was needed, although everyone else and in Stop/Pause video when Modal is closed (not using $ sign) contributed with everything that they got me to look up as well. #Phoenix1355 actually started me on the right path despite me not posting any code at all, in turn leading me to learn so much in very little about Javascript and HTML.
This has been plaguing me for at least a week (I've lost track of time making this website), researching, getting other setups, trying overly-complicated setups, being told it can only be done by paying for a hosting plan or having to use Wordpress.. And this Console.log output, sooo helpful omg. Thank you everyone who contributed!
Here is the finished code:
<html>
<head>
<link href="http://www.jolanxbl.ca/snips/modal.css" rel="stylesheet" />
</head>
<body>
<center>
<br><br><br><br><br>
<!--List of videos-->
<img data-vidcode="rLdpnu2dDUY" src="https://img.youtube.com/vi/rLdpnu2dDUY/hqdefault.jpg" width="200px">
<img data-vidcode="hDSansxhArU" src="https://img.youtube.com/vi/hDSansxhArU/hqdefault.jpg" width="200px">
<img data-vidcode="duBjWlIzpzQ" src="https://img.youtube.com/vi/duBjWlIzpzQ/hqdefault.jpg" width="200px">
</center>
<!-- Modal Section 1 -->
<div class="bg-modal">
<div class="modal-content">
<div class="close">+</div>
<div class="theVideo">
<iframe width="840" height="472" src="https://www.youtube.com/embed/rLdpnu2dDUY" frameborder="0" encrypted-media; picture-in-picture allowfullscreen></iframe>
</div>
</div>
</div>
<script>
let vidcode = 'rLdpnu2dDUY';
// Get all elements with classname 'thumbnail'
let thumbnails = document.getElementsByClassName('thumbnail');
// Loop for every element with class
Array.from(thumbnails).forEach(function(element) {
element.addEventListener('click', thumbnailClicked);
});
function thumbnailClicked(event) {
// Event is mouse click event
// target is the img (as that is what you click on)
// dataset is the data attributes of img
vidcode = event.target.dataset.vidcode;
console.log('vidcode: ', vidcode)
//document.querySelector(".gridContainer").addEventListener("click", function() {
document.querySelector(".theVideo").innerHTML = '<iframe width="840" height="472" src="https://www.youtube.com/embed/' + vidcode + '" frameborder="0" encrypted-media></iframe>';
document.querySelector(".bg-modal").style.display = "flex";
}
document.querySelector(".bg-modal").addEventListener("click", function() { //.bg-modal to make the surrounding clickable
document.querySelector(".bg-modal").style.display = "none";
document.querySelector(".theVideo").innerHTML = "";
});
</script>
</body>
</html>
Based on your description I think you are looking for something along the lines of the "data attribute". Data attributes are custom attributes you can assign to any DOM element that contain essentially whatever you want.
In you case if you have a page with lots of thumbnails and you want a specific action to happen when you click on a specific thumbnail, your best bet is if you store that unique identifier (the video id, or are you put it vidcode) on the element you are clicking on.
This can be done like this:
<body>
<!--List of videos-->
<img data-vidcode="rLdpnu2dDUY" src="https://img.youtube.com/vi/rLdpnu2dDUY/hqdefault.jpg">
<img data-vidcode="example2" src="img2.jpg">
<img data-vidcode="example3" src="img3.jpg">
<script>
let vidcode = 'rLdpnu2dDUY';
// Get all elements with classname 'thumbnail'
let thumbnails = document.getElementsByClassName('thumbnail');
// Loop for every element with class
Array.from(thumbnails).forEach(function(element) {
element.addEventListener('click', thumbnailClicked);
});
function thumbnailClicked(event) {
// Event is mouse click event
// target is the img (as that is what you click on)
// dataset is the data attributes of img
vidcode = event.target.dataset.vidcode;
console.log('vidcode: ', vidcode)
}
</script>
</body>
Try passing the vidcode as an parameter for modalviewer function and then use the value.
function modalviewer(vidcode){
var start = '<iframe width="840" height="472" src="https://www.youtube.com/embed/';
var end = '" frameborder="0" encrypted-media></iframe>';
var showVideo = start + vidcode + end;
document.querySelector(".theVideo").innerHTML = showVideo;
};
<div class="theVideo"></div>
Click
<script>
document.getElementById('hDSansxhArU').onclick = function() {
var vidcode = 'hDSansxhArU';
modalviewer(vidcode)
};
</script>

how to change several images with a single click

Im really new to javascript, and while Im learning, Im trying to change images in a gallery to others with an onclick function.
I have links to different galleries. When I click on link 1, the imgs are one1.jpg, one2.jpg and so on. When I click on link 2, imgs are two1.jpg, two2.jpg, etc.
This is the rough script I made for Link 1:
<script>
function one() {
document.getElementById("foto1").src="one1.jpg";
document.getElementById("foto2").src="one2.jpg";
}
</script>
Link 1
Link 2
<img id="foto1" src="tre1.jpg"></a>
<img id="foto2" src="tre2.jpg"></a>
etc.
I made another function called two() for the second link with same content but changing src to what I want. And for every link I add, I copy the script and change it a little.
I know there is a way to optimize to a single script with variables or something .
Any help?
Thanks
In order to differentiate group of images there must be a pattern.
try to add a class on each img tag to differentiate images for changing their source, and the you can loop through images as follows:
Link 1
Link 2
<img class="img1" id="foto1" src="foto1.jpg">
<img class="img1" id="foto2" src="foto1.jpg">
<img class="img2" id="foto3" src="pic1.jpg">
<img class="img2" id="foto4" src="pic2.jpg">
<script>
function one() {
var img = document.getElementsByClassName("img1");
for (var i in img) {
img[i].src = "foto" + 1 + ".jpg"
}
}
function two() {
var img = document.getElementsByClassName("img2");
for (var i in img) {
img[i].src = "pic" + 1 + ".jpg"
}
}
</script>

Image gallery thumbnails

I'm new to Java and need to build an image gallery.
I have a catalogue of images: each category has a thumbnail; each category has three images.
Process:
Click on thumbnail, bigPic changes its src to show the image you clicked on.
Three dots below bigPic can be clicked to see the other images in that category (so if another thumbnail is chosen, the srcs they pass onto bigPic will change too)
I have tried a few things and looked around but I cannot seem to make it work.
Here is what I have so far:
<script>
function backColor(a) {
document.getElementById("bigPic").src = a;
}
function varE(e){
var chosen = e;
document.getElementsByName("firstDot").id = chosen;
}
function setM(m) {
var chosenImage = m.id;
document.getElementById("bigPic").src = chosenImage;
}
</script>
bigPic:
<img class="bigPic" id="bigPic">
thumbnail image:
<img class="thumb" src="categoryImageSRC" onclick="backColor('anotherImageSRC'); varE('otherImageSRC')">
dot/circle that shows another image in category:
<img name="firstDot" id="" src="dotImageSRC" onclick="setM(this)">
Any ideas on how to go about this, examples and corrections are very welcome! Thank you!
get element by name returns an array of element so you need to change this line in varE function
document.getElementsByName("firstDot").id = chosen;
to
document.getElementsByName("firstDot")[0].id = chosen;

Tracking which image in a list of images is clicked?

I have a set of images that correspond to video thumbnails. The user clicks a thumb which loads the browser. This would be simple enough, but I need to track which of the thumbs was clicked, so that I can automatically cue up the next video in sequence.
My first thought was to do something like this (highly simplified example):
<div class="thumbs">
<img id="vt_0" src="thumbxxx00.jpg" />
<img id="vt_1" src="thumbxxx01.jpg" />
<img id="vt_2" src="thumbxxx02.jpg" />
<img id="vt_3" src="thumbxxx03.jpg" />
<img id="vt_4" src="thumbxxx04.jpg" />
<img id="vt_5" src="thumbxxx05.jpg" />
<img id="vt_6" src="thumbxxx06.jpg" />
</div>
<script type="text/javascript">
var videos = [ "xxx00", "xxx01", "xxx02", "xxx03", "xxx04", "xxx05", "xxx06" ];
var video_index = null;
function playVideo(id) {
// play video then call "onVideoFinish()" when video ends.
}
function onVideoFinish() {
video_index = (video_index = 6) ? video_index : video_index+1;
playVideo(videos[video_index]);
}
$j("div.thumbnail img").live("click", function (e) {
e.preventDefault();
var selected_id = $(this).attr("id").split("_")[1];
video_index = selected_id;
playvideo( videos[video_index] );
});
</script>
At first glance this seems to be okay, but I'm not sure if this is the best/most elegant solution, especially as I'd be implementing all these methods from within an object context.
This is how I would do it. The only global that you need in this case is currentPlayOrder, which could be stored someone as part of a preferences or configuration model.
First the HTML. I moved the video sources into the rel attribute of the associated thumbnail. I assume that your application is generating the thumbnails, in which case, this would be an appropriate method since whatever generates the thumbnail HTML could be made aware of the associated video sources.
<div class="thumbs">
<img id="vt_0" src="http://stackoverflow.com/content/img/so/logo.png" rel="videoA"/>
<img id="vt_1" src="http://serverfault.com/content/img/sf/logo.png" rel="videoB"/>
<img id="vt_2" src="http://stackoverflow.com/content/img/so/logo.png" rel="videoC"/>
<img id="vt_3" src="http://serverfault.com/content/img/sf/logo.png" rel="videoD"/>
<img id="vt_4" src="http://stackoverflow.com/content/img/so/logo.png" rel="videoE"/>
<img id="vt_5" src="http://serverfault.com/content/img/sf/logo.png" rel="videoF"/>
<img id="vt_6" src="http://stackoverflow.com/content/img/so/logo.png" rel="videoG"/>
</div>
Now the JS. Notice the use of previousSibling and nextSibling to determine play order:
<script type="text/javascript">
var PLAY_ORDER_BACKWARD = "previousSibling";
var PLAY_ORDER_FORWARD = "nextSibling";
var currentPlayOrder = PLAY_ORDER_FORWARD;
$(document).ready(function() {
$(".thumbs img").each(function(i, node) {
$(node).click(function() {
playVideo(this.getAttribute("rel"), this);
});
});
});
var playVideo = function(source, thumbNode) {
console.log("Play video %s", source);
onVideoFinish(thumbNode);
// If your video play accepts a callback, you may need to pass it as
// function() { onVideoFinish(thumbNode); }
}
var onVideoFinish = function(thumbNode) {
// Get the next img node (if any) in the appropriate direction
while ( thumbNode = thumbNode[currentPlayOrder] ) {
if ( thumbNode.tagName == "IMG" ) { break; }
}
// If an img node exists and it has the rel (video source) attribute
if ( thumbNode && thumbNode.getAttribute("rel") ) {
playVideo(thumbNode.getAttribute("rel"), thumbNode);
}
// Otherwise, assume that there are no more thumbs/videos in this direction
else {
console.log("No more videos to play");
}
}
</script>
Hope that helps.
Here's how I would do it.
Instead of storing the video names inside an array, why not store the video name along with the thumbnail?
You can use the class attribute to store the name of the video.
Once you take this approach, things become simple.
<div class="thumbs">
<img id="vt_0" src="thumbxxx00.jpg" class="xxx00"/>
<img id="vt_1" src="thumbxxx01.jpg" class="xxx01"/>
<img id="vt_2" src="thumbxxx02.jpg" class="xxx02"/>
<img id="vt_3" src="thumbxxx03.jpg" class="xxx03"/>
<img id="vt_4" src="thumbxxx04.jpg" class="xxx04"/>
<img id="vt_5" src="thumbxxx05.jpg" class="xxx05"/>
<img id="vt_6" src="thumbxxx06.jpg" class="xxx06"/>
</div>
<script type="text/javascript">
function setupVideoPlayer(order)
{
//lastThumb won't be accessible from outside of setupVideoPlayer
//function.
var lastThumb = null;
var imageSelector = 'div.thumbs img';
function playVideo(video)
{
//Play the video.
onVideoFinish();
}
function onVideoFinish()
{
//If order is 'ascending', we will go to the 'next'
//image, otherwise we will go to 'previous' image.
var method = order == 'asc' ? 'next' : 'prev';
//When user is at the end, we need to reset it either at the
//first image (for ascending) or the last (for descending).
var resetIndex = order == 'asc' ? 0 : $(imageSelector).length - 1;
//When video has finished playing, we will try to
//find the next/prev (depending upon order) sibling of 'lastThumb',
//If we can not find any sibling, it means we are at the
//last/first thumbnail and we will go back and fetch the first/last
//image.
//Also, instead of calling the playVideo method, we will
//fire the click event of thumbnail. This way, if you decide to
//do something in future (say playing an ad before the video)
//you only need to do it in your click handler.
if($(lastThumb)[method]().length == 0)
$(imageSelector).get(resetIndex).click();
else
$(lastThumb)[method]().click();
}
$j(imageSelector)
.click(
function()
{
//on click, we store the reference to the thumbnail which was
//clicked.
lastThumb = this;
//We get the name of the video from the class attribute
//and play the video.
playVideo($(this).attr('class'));
}
);
}
$(document).ready(
function() { setupVideoPlayer('asc'); }
);
</script>
Above code has the advantage that you can modify your HTML and it will automatically play those videos.
You can wrap the images with an anchor tag and use the onClick method as follows:
<img src="thumbxxx00.jpg" />
<img src="thumbxxx01.jpg" />
...

Categories

Resources