I am quite new at JQuery (in fact, new to JS too) and I am trying to add a fade in effect to a JS function wich I wrote to change images in a photo gallery when the "thumbnail" of another image is selected. Code is:
//For HTML - the "thumbs" area:
<img id="g1" class="thg" onclick="trocafoto(this.id)" src="fotos/sopa.jpg">
<img id="g2"class="thg" onclick="trocafoto(this.id)" src="fotos/salmao.jpg">//and so on
//The place where pictures are displayed:
<img class="portif" id="alvo" src="fotos/sopa.jpg">
//The JS Function itself:
function trocafoto(id) {
var x = document.getElementById(id).src ;
document.getElementById("alvo").src = x;
}
I'd like to add a JQuery Fade Out effect for the previous image displayed, and the Fade In for the last selected image once the funcion is fired. But I am not finding a way to mix the JQuery Code with the plain JS... How could I call only the JQuery function without need to target it to the same element again?
Thanks in advance for any help.
Try this:
var $alvo = $('#alvo');
$('.thg').on('click', function(){
var clickedImgSrc = $(this).attr('src');
// first hide alvo
$alvo.fadeOut( "slow", function() {
// fadeOut Animation is complete.
// Add the new src to alvo and fadeIn
$(this).attr('src', clickedImgSrc).fadeIn();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="g1" class="thg" src="fotos/sopa.jpg">
<img id="g2" class="thg" src="fotos/salmao.jpg">
<img class="portif" id="alvo" src="fotos/sopa.jpg">
Instead of this
document.getElementById("alvo")
You can reach an element using
$("#alvo")
So in your case
$("#alvo").fadeOut();
would work for example.
If you're using thumbnails than probably you do have higher resolution images too.
That's good for faster page loading! So in that case store the higher quality image path inside a data-* attribute like:
var $alvo = $("#alvo"); // The larger target image
$(".thg").on("click", function(){
// First, make sure the HQ image is loaded from the server
var img = new Image();
$(img).on("load", function(){
// Than assign it to #alvo
$alvo.hide().prop("src", img.src).fadeIn();
});
// getting the path from data attribute of the clicked thumbnail
img.src = this.dataset.hq;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="thg" src="//placehold.it/60x60/cf5" data-hq="//placehold.it/400x200/cf5">
<img class="thg" src="//placehold.it/60x60/f5c" data-hq="//placehold.it/400x200/f5c">
<br>
<img id="alvo" src="//placehold.it/400x200/cf5">
If you don't want the loading image delay than you could preload in a loop all the HQ images, but that defies the purpose of faster page load. A remedy could be adding a loading spinner when a thumbnail is clicked.
Related
Edit: Sorry if I reply late to any solutions because I need time to figure out how they work haha
I am a beginner in Javascript and I am currently trying to use this piece of code to change an image on mouseover
// Mouseover change (Ciel):
function rollover(my_image){
my_image.src = "images/ci2_a.png";
}
function mouseaway(my_image){
my_image.src = "images/ci_a.png";
}
and this is the corresponding HTML
<img src="images/ci_a.png" onmouseover="rollover(this)" onmouseout="mouseaway(this)" alt="xxx" style="float:left; width:38%">
This works fine, but I want to do it for more than one image on the same page (a different image rollover for each picture) . Even after changing the name of the functions and stuff it doesn't work. The first image stops changing onmouseover immediately when I try to add a similar function for the next image. Could someone tell me how to perform similar events on more than one image (not concurrently)? Thank you!
You could add event listeners to all the image elements you'd like.
<img class="my-image" src="images/ci_a.png" onmouseover="rollover(this)" onmouseout="mouseaway(this)" alt="xxx" style="float:left; width:38%"/>
function rollover(){
this.src = "images/ci2_a.png";
}
function mouseaway(){
this.src = "images/ci_a.png";
}
const myImages = document.querySelectorAll('.my-image')
myImages.forEach(img => {
img.addEventListener('mouseenter', rollover)
img.addEventListener('mouseleave', mouseaway)
})
You can send the image file as the second parameter like this:
function rollover(element, image) {
element.src = image
}
...
<img onmouseover="rollover(this, 'images/ci2_a.png')" ...>
But my question is why do you need JavaScript for that? You can use a simple CSS to achieve this.
Since you need different images on load and on hover, you need a single way to define this functionality across a collection of images.
Building on Matthew's approach, here's a way to do that.
JSFiddle to test it real-time.
You'll dynamically generate the images using data attributes to store the alternate (hover) image URL.
<img class="pics" src="https://picsum.photos/id/0/100"
data-swap="https://picsum.photos/id/10/100">
<br>
<img class="pics" src="https://picsum.photos/id/1/100"
data-swap="https://picsum.photos/id/11/100">
<br>
<img class="pics" src="https://picsum.photos/id/2/100"
data-swap="https://picsum.photos/id/12/100">
<br>
<img class="pics" src="https://picsum.photos/id/3/100"
data-swap="https://picsum.photos/id/14/100">
Then define the event listeners for all elements with the class pics. Here's a list of all the events that can be referenced.
On mouseover, store the original image in a data element original.
Then change the src with the value of the data-swap.
On mouseout, replace the src with the original value.
const myImages = document.querySelectorAll('.pics')
myImages.forEach(img => {
img.addEventListener('mouseover', function () {
img.dataset.original = img.src;
img.src = img.dataset.swap;
});
img.addEventListener('mouseout', function () {
img.src = img.dataset.original;
});
})
For some reason, when I use the attribute onload on my img tag, it causes my images to flicker. Ideally, when I load the page, an image is displayed and when I refresh the page, the image is changed.
Here's my tag as well as the function for it:
HTML
<img id="randomimage" onload="randomImg()" src="images/carmainpic.jpg" alt="main pic of car"/>
JavasScript
function randomImg(){
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
}
Because the function you're calling changes the image's src to a random pick from the array, triggering a new load event, which changes the src randomly again, etc. On at least some browsers the cycle probably stops when you happen to assign the URL the image already has, too.
If your goal is to just show one of those images, at random, you can do that by leaving src off the img entirely and then adding it (once) with script (either immediately following the img in order to avoid your layout having to be adjusted when you add it, or in script at the end of the page if you prefer; no need to wait for any event):
<img id="randomimage" alt="main pic of car"/>
<script>
(function() {
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random() * images.length); // <== Note change, so adding images to the array Just Works
document.getElementById("randomimage").src=images[num];
})();
</script>
Even if you put the script immediately after the <img ...> tag, the img element will be available to the script. So your choice whether to do it inline or with the other scripts at the end of the page.
The randomImg function is called every time the image loads. You can use a flag variable to make sure that you only change the image once:
var changed = false;
function randomImg(){
if (!changed) {
changed = true;
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
}
}
The problem is that you are listening to the load event on the image, instead of the page.
onload="randomImg()"
So, as soon as the first image loads, it triggers the function randomImg which causes change of src attribute on the image. So the browser will attempt to assign a new image to the element, and yet another load event is triggered, which repeats the entire cycle.
Instead, if you want to choose a random image when the page loads, you can listen to DOMContentLoaded event on the document, and choose a random image.
document.addEventListener("DOMContentLoaded", function() {
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
console.log("Showing: " + images[num]);
});
<img id="randomimage" src="images/carmainpic.jpg" alt="main pic of car"/>
Note: Since you are selecting a random image, it is not guaranteed that you will always get a different image when the page is refreshed. Instead, if you must get a different image on refreshing the page, you can perhaps persist the image identifier in localStorage, and use that to determine the next image to display.
Well you can use $(document).ready(function(){}) to do that. Because you want when charge the page that function execute it.
$(document).ready(function(){
function randomImg(){
var images=["https://www.bensound.com/bensound-img/romantic.jpg","https://www.psdstack.com/wp-content/uploads/2016/10/featured-copyright-free-mages.jpg","http://shaebaxter.com/wp-content/uploads/2015/04/Life-of-Pix-free-stock-photos-sea-peaople-water-waves-back-Sunset-Joshua-earle-1024x682.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
}
randomImg();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="randomimage" src="" alt="main pic of car"/>
I've been trying for a few hours to select the center image (or current image) in my carousel. Once selected, I'd like to display the same image in a center-of-screen view-port; think scrolling through photo previews while the current photo is in a larger display. As you scroll, the center image is dynamically changing so the view port will too.
Here is my HTML where I'm trying to propogate said carousel image; the view port:
<div class="col-md-6" style="height:480px;border:1px solid #fff">
<div id="view-port">
</div>
</div>
The closest I've gotten to something successful is:
window.onload = function() {
var centerSlide = document.createElement("img");
centerSlide.src = $('#myCarousel').slick('slickCurrentSlide');
document.getElementById("view-port").appendChild(centerSlide);
console.log(centerSlide);
};
Which logs
<img src="0">
as expected, the index of the currentSlide. This can be observed here:
https://jsfiddle.net/positivecharge8/nddaj84x/
But I can't figure out how to get the image so I can reference it to put into a div. I understand that the code that I have now won't dynamically change the view port div image as I scroll through the carousel- that's okay, for now I'd like to at least get some image up there. Thanks!
Using $('#myCarousel').slick('slickCurrentSlide'); gets you the index of the current image not the src of the image. Use jQuery's prop function to get the src of the image.
The following will find the current slide, and then get its src and use it for the new image's src.
var centerSlide = document.createElement("img");
centerSlide.src = $('#shoe-carousel .slick-current img').prop('src');
document.getElementById("view-port").appendChild(centerSlide);
Here is a working example: https://jsfiddle.net/4g4wbj1g/8/
To make the centerSlide update on slide change I would look into using the afterChange event. There is some good documentation here: http://kenwheeler.github.io/slick/
You can hook into the afterChange event of slick
<div id="slickme">
<div class="myelement"><img src="http://kenwheeler.github.io/slick/img/fonz2.png"></div>
<div class="myelement"><img src="http://kenwheeler.github.io/slick/img/fonz3.png"></div>
</div>
// On slide change
$('#slickme').on('afterChange', function(event, slick, currentSlide){
console.log(currentSlide);
//get the element dom from the page
console.log($('#slickme .myelement[data-slick-index = ' + currentSlide + ']').html());
});
Then you can use whatever selectors you want, if you wanted the img src you could use something like:
$('#slickme .myelement[data-slick-index = ' + currentSlide + '] img').attr('src');
So, I am attempting to load an image in jQuery, on hover, to another div without a delay for load times.
HERE IS A WORKING EXAMPLE
Raw code:
HTML:
<div id="hover" data-img="http://lorempixel.com/output/animals-q-c-370-289-5.jpg">
HOVER OVER ME
</div>
<div id="image">
<span>
<img data-img="http://lorempixel.com/output/technics-q-c-370-289-4.jpg" src="http://lorempixel.com/output/technics-q-c-370-289-4.jpg" />
</span>
</div>
jQuery:
$('#hover').on('mouseenter', function() {
var newImg = $(this).attr('data-img');
$('#image > span > img').attr("src", newImg);
});
$('#hover').on('mouseleave', function() {
var oldImg = $('#image > span > img').attr('data-img');
$('#image > span > img').attr("src", oldImg);
});
As you can see, the image of the animal takes a little while to load. I need to remove this delay completely so that the image of the animal is displayed right away upon hover.
Things I have tried:
I tried reducing my images file size from 120kb down to just 20kb,
still no luck.
I tried loading my images to a hidden div upon page load so that
they already existed within the page, instead of just within a
data attribute, still no luck.
PS. The version on my site contains more than 30 images, while the example is only using two. The example has very small images that could possibly be loaded straight away with fast internet. We have horrible internet speeds in our office, so if the images load straight away, try sourcing some larger images to see the problem at hand.
Try a simple preloading technique like
$('#hover').on('mouseenter', function() {
var newImg = $(this).attr('data-img');
$('#image > span > img').attr("src", newImg);
});
$('#hover').on('mouseleave', function() {
var oldImg = $('#image > span > img').attr('data-img');
$('#image > span > img').attr("src", oldImg);
});
//preload here
new Image().src = $('#hover').data('img');
What you can do is put an actual <img src="url"> and hide it through css.
This way, the image will have been loaded already and there will be no delay when you hover over the image.
Try this:
<div id="hover" data-img="http://lorempixel.com/output/animals-q-c-370-289-5.jpg">
HOVER OVER ME
</div>
<div id="image">
<span>
<img data-img="http://lorempixel.com/output/technics-q-c-370-289-4.jpg" src="http://lorempixel.com/output/technics-q-c-370-289-4.jpg" />
</span>
</div>
<img src="http://lorempixel.com/output/animals-q-c-370-289-5.jpg" style="display:none">
Live Demo
If you don't want delay, then you have to load the image BEFORE you show it via hover. Arun's answer will work.
Another option is to use an image sprite. Put both images together as one image file. Then reposition it so that the appropriate part of it is shown via CSS.
By setting the "src" attribute the browser parses and tries to load the specified image.
I suggest you to hide/show div element already containing the image like this.
<div id="hover" data-img="img-id-1">
HOVER OVER ME
</div>
<div id="img-id-1" style="display:none"><img src="/path/to/img.png"/></div>
<div id="image"></div>
$(document).on('mouseenter', '#hover', function() {
var id = $(this).attr('data-img');
$('#image').html($(id).html());
});
$(document).on('mouseleave', '#hover', function() {
$('#image').empty();
});
I have not added the default image to display it first. It should be easy to add however.
I'm trying to find a simple, but bulletproof way of hiding an image until it's loaded, and then giving it some jQuery effects (e.g. fadeIn) but all the methods I've found seem to have some issues. For example, this solution:
<img id="photo" src="bigimage.jpg" style="display:none" />
$("#photo").load(function() {
$(this).fadeIn("slow");
});
May not trigger if the image is loaded before the DOM is ready (load() won't fire).
So I wrote the following, which only adds the URL once the image has definitely loaded...
$.fn.ImageLoad = function(url){
$image = $(this);
$("<img >").attr("src", url).load(function(){
$image.attr("src", url);
});
return $image;
};
$("#cast").ImageLoad("http://pas-wordpress-media.s3.amazonaws.com/wp-content/uploads/2013/08/Google-Office-Building-in-NYC.jpg").fadeIn("slow");
But it only runs the fadeIn("slow") once the image has been cached by the browser. The first time it loads, it just appears with no effects.
See your yourself here: http://jsfiddle.net/KKn4N/
Is there any way I can fix this?
Here is my version. Works every single time and completely cross browser.
$.fn.ImageLoad = function(url){
$this = $(this);
$this.hide().on('load', function(){
$this.fadeIn();
});
this[0].src = url;
};
The key is to
do the fade inside a callback
hide first
listen for the .load before you set the .src
DEMO
Yea, load the image first, then attach the fadeIn afterwards.
$.fn.ImageLoad = function(url){
$image = $(this);
$("<img >").attr("src", url).load(function(){
$image.attr("src", url);
});
return $image;
};
$("#cast").ImageLoad("http://www.wired.com/wiredenterprise/wp-content/uploads/2013/07/ff_googleinfrastructure_large.jpg");
$("#cast").fadeIn("slow");
Try this
<img
id="cast"
style="display:none"
src="http://pas-wordpress-media.s3.amazonaws.com/wp-content/uploads/2013/08/Google-Office-Building-in-NYC.jpg"
onload="$(document).ready(function(){$('#cast').fadeIn('slow')})"
/>
Not sure if I get it correctly - I'm assuming you mean hide all images when page loads until all images are loaded and then fade them in?
If so, then why not just set display:none on images (maybe give them a class .hidden {display:none}) and then wait for window load event (i.e. all loaded) and trigger fade on all images - they will then nicely all fade in at the same time.
$('img.hidden').fadeIn('slow');
Example:
html
<img class=hidden src=http://cdn-4.lifehack.org/wp-content/files/2013/09/javascript-logo.png></img>
css
.hidden{
display:none;
}
js
$(window).load(function(){
$('img.hidden').fadeIn('slow');
});