I am using an AOS (animate-on-scroll) library in my html to help fade in the images, but javascript to trigger the actual fading-in. I want the image to fade-in when I am scrolling past, but not to fade back out when I scroll back up. The code below is what I've tried so far, but the image isn't showing up. I've seen a way to do this in jQuery, but I wanted to see if I could do it in plain JS. I got the image to show up and fade-in using the onscroll handler, but ran into the problem of it fading-in repeatedly if I moved back to the top of the page. Below is what I have using an event listener
HTML:
//sets the point at which the image will fade in
let pic = document.getElementById("pic");
let characterCaption = document.getElementById("characters");
let triggerAt = 100;
function getPic() {
pic.onscroll;
let topOfImage = pic.scrollTop + triggerAt;
return topOfImage;
}
window.addEventListener("scroll", fadeInImage);
//attempt to fade in image at certain point and prevent image from fading in again
function fadeInImage() {
let currentPosition = window.pageYOffset;
let topOfImage = getPic();
if (currentPosition > topOfImage) {
pic.style.visibility = "visible";
characterCaption.style.visibility = "visible";
window.removeEventListener("scroll", fadeInImage);
}
}
<img id="pic" src="https://cdn.vox-cdn.com/thumbor/MZRJnpwAMIHQ5-XT4FwNv0rivw4=/1400x1400/filters:format(jpeg)/cdn.vox-cdn.com/uploads/chorus_asset/file/19397812/1048232144.jpg.jpg" width="500px" height="650px" data-aos="fade-left" data-aos-duration="2000" data-aos-easing="ease-in-sine">
<p id="characters"> picture caption </p>
Related
I want the user to enter a specific number and display that many images with the help of Unsplash API, but when the function calling the API is called there is a gap of 5 seconds before images finally appear on screen, and in that gap, I want to display a gif(loader) and hide it when images are finally visible on DOM, but I am not able to achieve this, can someone help
let imgNum = document.querySelector('#num')
let btn = document.querySelector("#btn")
let output = document.querySelector("#output")
let loadImg = document.querySelector("#load") // gif image
let url = "https://source.unsplash.com/random"
loadImg.style.visibility = 'hidden';
function disLoad() {
loadImg.style.visibility = 'visible';
}
function hideLoad() {
loadImg.style.display = "hidden"
}
function displayFunc() {
disLoad()
let img = ""
for (let i = 0; i < Number(imgNum.value); i++) {
let newImg = `<img src=${url}>`
img += newImg
}
hideLoad()
output.innerHTML = img
}
btn.addEventListener("click", displayFunc)
<!-- GIF in HTML -->
<div id="num"></div>
<button id="btn">button</button>
<div id="output">
<img src="https://media.tenor.com/lwoULCdn-y4AAAAC/placeholder-text.gif" id="load">
</div>
This is because the UI and your JS run on the same thread, so you add and remove the loading gif (after your processing is complete!) without the UI showing it.
You would need to add the gif and then run your processing, as a separate function, within a setTimeout() with a timeout of 0.
Detailed answer here
I'm using IntersectionObserver to replace an initially-loaded image with another one as the original image comes into the user's viewport.
I want the image to fade in, as opposed to just straight replacement.
I've tried adding a Jquery loader to the image, but it is not working as I'd like.
function fadeIn(obj) {
$(obj).fadeIn(1000);
}
document.addEventListener("DOMContentLoaded", function() {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
if ("IntersectionObserver" in window) {
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
$(lazyImage).on('load', fadeIn(lazyImage));
lazyImage.src = lazyImage.dataset.src;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<img
class="lazy"
src="https://classroomclipart.com/christmas-tree-with-bright-lights-decoration-animated-clipart-motion-lights-gifts-presents-2.gif"
data-src="https://classroomclipart.com/TN_december-happy-holidays_2.jpg"
data-srcset="https://classroomclipart.com/sm-santa-claus-and-reindeer-singing-christmas-carols-clipart.jpg 2x, https://classroomclipart.com/TN_december-happy-holidays_2.jpg 1x"
width="100"
height="100"
>
Here is a solution that works decently well using jQuery animation: https://jsfiddle.net/ea7fxrL5/
There are two problems in your current code as far as I can tell:
The fadeIn function is actually being called before the image's source is changed to the "TN_december-happy-holidays_2.jpg" image because the load event is triggered immediately on intersection, since the image's "christmas-tree" src has already been loaded.
The image is already at full opacity, so it needs to be hidden before you can fade it in.
Hope this helps!
I have a "slideshow" type of function where images fade in and out to each other. It works fine, but when it fades, it is fading the first picture out to white and then the second picture fades in. What I want is for the first image to fade right into the second (with no empty white background in between). Can I do this?
Here is an example: http://jsfiddle.net/aegtjm5y/5/
image
<img id="image1" src="http://9pixs.com/wp-content/uploads/2014/06/dog-pics_1404159465.jpg" style="width: 100%;">
JS
var curIndex = 0;
var src = ['/images/IMG_20140907_203614.jpg', 'http://9pixs.com/wp-content/uploads/2014/06/dog-pics_1404159465.jpg', 'http://cvcl.mit.edu/hybrid/cat2.jpg'];
var fadeTimeInMilliseconds = 2000;
var waitTimeInMilliseconds = 1000;
$(document).ready(function(){
switchImageAndWait(true);
});
function switchImageAndWait(fadeOut2){
if(fadeOut2){
setTimeout(fadeOut, waitTimeInMilliseconds);
}else{
var index = Math.floor((Math.random()*src.length))
if(curIndex == index){
index++;
if(index >= src.length){
index-=2;
}
}
curIndex = index;
$("#image1").attr("src", src[index]);
fadeIn();
}
}
function fadeOut(){
$("#image1").fadeTo( fadeTimeInMilliseconds, 0 , function() { switchImageAndWait(false); });
}
function fadeIn(){
$("#image1").fadeTo( fadeTimeInMilliseconds, 1 , function() { switchImageAndWait(true); });
}
Edit: "Can I do this?" - No. You can't do this using only one image element.
What you basically need is two images one on top of the other.
I edited your fiddle and it's working fine:
JSFiddle
So basically I added another img element and set the position of the images to be absolute (so they are overlaying).
<img id="image2" src="http://cvcl.mit.edu/hybrid/cat2.jpg" style="width: 100%;position: absolute;">
I updated the javascript stuff so the images get changed in both fadeIn and fadeOut "events". The principle is that the upper image gets faded out and faded In. When it's not visible you change the src of it. And when it is visible you change the src of bottom image.
I can't think of better solution now. Hope this helps..
I have a code where onclick a word on left side of the page, it shows some text on right hand side of page. Here's the jsfiddle of working code.
Now, my problem is I want to display spinning circle on page on every onclick and then show text on the right hand side of the page. My code for spinning circle is:
HTML:
<div id="loading">
<img src="http://jimpunk.net/Loading/wp-content/uploads/loading1.gif"/>
</div>
JavaScript:
function hideLoading() {
document.getElementById("loading").style.display = 'block';
}
function showLoading() {
document.getElementById("loading").style.visibility = 'visible';
}
CSS:
#loading {
display: none;
}
Now, I don't know how to place them in my working code to get the desired result. Anybody knows the correct way of doing it?
Desired result: onclick "abc" on left hand side, spinning circle should be displayed for 1 sec and then "I should be printed on left side" should be displayed. Again on clicking "mno", first spinning circle should be shown for 1 sec and then text "I should be printed on left side" will be displayed. The fiddle has working version of onclick.
You should use a single handler function on each element that will both hide and show the loading gif. Also, it's a good idea not to use getElementById on every call, so save it in a variable:
<div id="container">
<div id="header">
<h1>Main Title of Web Page</h1>
Here I am trying to split the webpage into two columns and display text.</div>
<div id="one">
<div id="loading">
<img src="http://support.snapfish.com/euf/assets/images/answer_images/SpinningWheel.gif" />
</div>
<div id="message"></div>
</div>
<div id="two"> <b>This is test one<br /></b>
<b>This is test two<br /></b>
</div>
Javascript:
var elements = {};
function loadSpanContent() {
elements.loading.style.display = 'block'; // Show loading gif
spanContent = this.innerHTML
setTimeout(function () {
elements.message.innerHTML = "I should be printed on left side - " + spanContent;
elements.loading.style.display = 'none'; // Hide loading gif
alert("onclick Event detected! " + spanContent);
}, 1000);
}
window.onload = function mydisplayArray() {
var array = ['abc', 'xyz', 'mno'];
elements.loading = document.getElementById("loading");
elements.one = document.getElementById("one");
elements.message = document.getElementById("message");
for (i = 0; i < array.length; i++) {
var span = document.createElement('span');
span.innerHTML = array[i];
span.onclick = loadSpanContent;
one.appendChild(span);
}
};
Here is a fiddle: http://jsfiddle.net/nBaCJ/1/
I'm still confused by what you actually want here, but if you want to have the loading message disappear after one second, you should use setTimeout. Something like this:
function showAlert() {
showLoading();
setTimeout(hideLoading,1000);
//Hide loading circle
var myString = "I should be printed on left side";
document.getElementById("two").innerHTML = myString;
}
But you also need to fix your "showLoading" and "hideLoading". Something like this:
function hideLoading() {
document.getElementById("loading").style.display = 'none';
}
function showLoading() {
document.getElementById("loading").style.display = 'block';
}
http://jsfiddle.net/7uxHC/9/
BTW: if you want your loading gif to appear over your content, then set its position:absolute in css, but note that you gif has a white, rather than transparent background so it will obscure your content.
Your request isn't clear.
But first, you should fix these 2 functions:
function hideLoading() {
document.getElementById("loading").style.display = 'none';
}
function showLoading() {
document.getElementById("loading").style.display = 'block';
}
Hi im trying to achieve a "news slider" like the one you can see in yahoo.com... I almost have the 100% of the code.. (if you want to compare them here is my code http://jsfiddle.net/PcAwU/1/)
what is missing in my code , (forget about design) is that , In my slider you have to clic on each item, i tried to replace Onclick for Hover on the javascript, it worked, but the fisrt image on the gallery stop working, so when you just open the slider, you see a missing image.
Other point.. also very important, in yahoo.com after "x seconds" the slider goes to the next item, and so on ... all the Thumnails are gruped 4 by for 4, (in mine 5 by 5, thats ok) ... after pass all the 4 items, it go to the next bloc..
HOW CAN I ACHIEVE THAT!!. I really looked into the API, everything, really im lost, i hope someone can help me. cause im really lost in here.
Thanks
Here is the script
$(function() {
var root = $(".scrollable").scrollable({circular: false}).autoscroll({ autoplay: true });
$(".items img").click(function() {
// see if same thumb is being clicked
if ($(this).hasClass("active")) { return; }
// calclulate large image's URL based on the thumbnail URL (flickr specific)
var url = $(this).attr("src").replace("_t", "");
// get handle to element that wraps the image and make it semi-transparent
var wrap = $("#image_wrap").fadeTo("medium", 0.5);
// the large image from www.flickr.com
var img = new Image();
// call this function after it's loaded
img.onload = function() {
// make wrapper fully visible
wrap.fadeTo("fast", 1);
// change the image
wrap.find("img").attr("src", url);
};
// begin loading the image from www.flickr.com
img.src = url;
// activate item
$(".items img").removeClass("active");
$(this).addClass("active");
// when page loads simulate a "click" on the first image
}).filter(":first").click();
// provide scrollable API for the action buttons
window.api = root.data("scrollable");
});
function toggle(el){
if(el.className!="play")
{
el.className="play";
el.src='images/play.png';
api.pause();
}
else if(el.className=="play")
{
el.className="pause";
el.src='images/pause.png';
api.play();
}
return false;
}
To fix the hover problem you need to make some quick changes: Change the click to a on(..) similar to just hover(..) just the new standard.
$(".items img").on("hover",function() {
....
Then You need to update the bottom click event to mouse over to simulate a hover effect. Trigger is a comman function to use to trigger some event.
}).filter(":first").trigger("mouseover");
jSFiddle: http://jsfiddle.net/PcAwU/2/
Now to have a play feature, you need a counter/ and a set interval like so:
var count = 1;
setInterval(function(){
count++; // add to the counter
if($(".items img").eq(count).length != 0){ // eq(.. select by index [0],[1]..
$(".items img").eq(count).trigger("mouseover");
} else count = 0; //reset counter
},1000);
This will go show new images every 1 second (1000 = 1sec), you can change this and manipulate it to your liking.
jSFiddle: http://jsfiddle.net/PcAwU/3/
If you want to hover the active image, you need to do so with the css() or the addClass() functions. But You have done this already, All we have to do is a simple css change:
.scrollable .active {
....
border-bottom:3px solid skyblue;
Here is the new update jSFilde: http://jsfiddle.net/PcAwU/4/