How can I change an image when the user scrolls down? - javascript

I can easily animate on scroll down png and jpg format images easily, but when I scroll down gif images, It repeatedly animated when I scroll down more.
this is the script i use
<script type="text/javascript">
$(function () {
$(window).scroll(function () {
if ($(this).scrollTop() > 10) {
$('.navbar-brand-img img').attr('src','asserts/images/innvert.gif');
}
if ($(this).scrollTop() < 49) {
$('.navbar-brand-img img').attr('src','asserts/images/expand.gif');
}
})
});
</script>
Anyone can help
I want to animate logo of gif images i provide the model website that animation used
Thrashio

Setting the src= of an image will always restart the image if it's animated, even if it's the same src=. Your issue is that you re-set the src= (to the same value) on every scroll so it's constantly restarting.
You can store whether or not you've already set the image - a simple flag (or .data on the img) would suffice.
$(function() {
$(window).scroll(function() {
// set to true/false here based on your initial image
var invert = false;
if ($(this).scrollTop() > 10) {
if (!invert) {
$('.navbar-brand-img img').attr('src', 'asserts/images/innvert.gif');
invert = true;
}
}
if ($(this).scrollTop() < 49) {
if (invert) {
$('.navbar-brand-img img').attr('src', 'asserts/images/expand.gif');
invert = false;
}
}
})
});
Note your >10 doesn't match with <49 so may cause problems.

Related

Return images back to normal when user scrolls to top again

I have 2 static (html position: fixed;) images at the edges of the screen (right and left). When users scrolls more than 100 pixels from top, these edges retract 50 pixels.
I want to them to reappear (normal again, as they were at the beginning) when users scrolls back to top. I tried adding boolean value which is true when they retract and added it to condition when they need to reappear again. But it isn't working. Why?
userHasScrolled = false;
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100) {
$(".rightstatic").animate({marginRight:'-50px'}, 900);
$(".leftstatic").animate({marginLeft:'-50px'}, 900);
userHasScrolled = true;
}
});
});
if($(window).scrollTop() <= 0 && userHasScrolled) {
$(".rightstatic").animate({marginRight: '+50px'}, 400);
$(".leftstatic").animate({marginLeft:'+50px'}, 400);
userHasScrolled = false;
}
Edit:
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100) {
$(".rightstatic").animate({marginRight:'-20px'}, 900);
$(".leftstatic").animate({marginLeft:'-20px'}, 900);
} else if($(window).scrollTop() <= 0) {
$(".rightstatic").animate({marginRight: '+0px'}, 400);
$(".leftstatic").animate({marginLeft:'+0px'}, 400);
}
});
});
It kinda works, but has a HUGE delay. Like more than a minute after reaching top it retracts back.
Edit 2: After throttling it finally works. Thanks #TomaszBubaƂa.
It isn't working because the bottom part of your code is called only once and userHasScrolled is false by that time. You need to combine both inside $(window).scroll(). I think you can get rid of userHasScrolled variable and second condition could be just else instead of else if.
var scrollTimeout;
var throttle = 250;
$(document).ready(function(){
$(window).scroll(function(){
if(scrollTimeout) return;
scrollTimeout = setTimeout(function() {
scrollTimeout = null;
const scrolled = $(this).scrollTop();
if (scrolled > 100) {
console.log("1");
$(".rightstatic").animate({marginRight:'-20px'}, 900);
$(".leftstatic").animate({marginLeft:'-20px'}, 900);
} else {
console.log("2");
$(".rightstatic").animate({marginRight: '+0px'}, 400);
$(".leftstatic").animate({marginLeft:'+0px'}, 400);
}
}, throttle);
});
});
Fiddle: https://jsfiddle.net/wctxbynt/41/
EDIT:
It wasn't working as intended since scroll event is fired multiple times (tens of times) with a single mousewheel interaction, causing jQuery animate to be called far too many times than it needs to be. A common way to fix this problem is to "throttle" a function not to be called unless a certain amount of time has passed. In edited code above we define timeout as 250ms, which means that our scroll handler code will get called up to 4 times a second - not more (a big difference as opposed to ex. 30 times in 100ms which is huge improvement in performance). Above is just an easy implementation of throttle function - read more about throttling here.

How to avoid the "blink" when exchanging gifs?

I am creating a website where when you scroll into an area, a gif appears. It only loops once; if you continue scrolling, it changes to another gif (which plays only once, too) If you scroll back, it changes to the first gif, restarting it so it can play again.
However, when the changing occurs, there is a blink that I do not want. Here is the fiddle. And here is the javascript:
$(window).ready(function() {
var v = 0;
$(window).on("scroll", function() {
var scrollTop = $(this).scrollTop();
if (scrollTop > 100 && scrollTop < 200) {
if ($('#container').attr('data-img') != 'http://i.imgur.com/Hhmt8.gif') {
++v;
$('#container').attr('data-img', 'http://i.imgur.com/Hhmt8.gif');
$('#container').css('background-image', 'url(http://i.imgur.com/Hhmt8.gif?v=' + v + ')');
}
} else if (scrollTop >= 200) {
if ($('#container').attr('data-img') != 'http://i.imgur.com/TUAwA.gif') {
++v;
$('#container').attr('data-img', 'http://i.imgur.com/TUAwA.gif');
$('#container').css('background-image', 'url(http://i.imgur.com/TUAwA.gif?v=' + v + ')');
}
} else {
$('.imageHolder').css('background', 'blue');
}
});
});
I tried removing the ?v='+v+' from the background-image but then it won't load everytime it changes... Is there a way to keep the functioning as it is without the blinking?
Preload the second image, the blinking comes from the remote fetching time of the image. If you had preloaded the same image at any point on this website before, the new image will be loaded directly from the browser's cache and will replace the previous one without any visible transition.
$(window).ready(function () {
var v = 0;
var image = new Image();
image.src = 'http://i.imgur.com/TUAwA.gif';
$(window).on("scroll", function () {
/* ... */
}
}

Using jQuery in certain screen sizes

I need a mobile navigation to stick after the user has scrolled a certain amount. When a user has scrolled 205px on desktop resolution the navigation will stick no problem.
How do I change this to 64px after the screen size has gone below 767px? and how do I cancel the desktop jQuery from taking effect on a mobile?
Current desktop javascript:
$(window).scroll(function(){
if ($(this).scrollTop() > 205) {
$('.sidemenu').addClass('fixed');
} else {
$('.sidemenu').removeClass('fixed');
}
});
Current mobile javascript:
function checkPosition() {
if (window.matchMedia('(max-width: 767px)').matches) {
$(window).scroll(function(){
if ($(this).scrollTop() > 64) {
$('.sidemenu').addClass('fixed');
} else {
$('.sidemenu').removeClass('fixed');
}
})
}
};
Suggestions would be much appreciated.
Thank you.
You can add a class mobile to your body for example when the matchmedia matches.
$(document.body).toggleClass('mobile', window.matchMedia('(max-width: 767px)').matches);
Once you have that, the checkPosition simply has to get the proper scrollTop value.
function checkPosition() {
var scrollY = $(document.body).hasClass('mobile') ? 64 : 205;
$('.sidemenu').toggleClass('fixed', $(window).scrollTop() > scrollY);
};
Or simply add the matchMedia test instead of the hasClass test.
Additionally, I expect the height of the "fixed container" to be dynamic.
Maybe something like:
var scrollY = $('header').height(); // just an idea ofcourse to get 64 or 205.
You can check screens size in resize wvent like this
var width;
$(window).resize(function () {
width = $("html").width();
});
than in scroll event (or in other place) you can check:
if (width <= 767) {
// do some for small screen
}
else if (width > 767 && width < 1200) {
// do some for medium screen
}
//if..

Replace logo image upon scroll down JS / HTML / CSS wordpress website

I would like to have a logo image change (for the purpose of color) upon scrolling.
The navigation currently changes when scrolling downwards to have a dark bar behind it, does anybody have any suggestions as to what will work best for this image replacement?
I have tried using this as found in another SO question but wouldn't work for me....
$(function(){
$(window).scroll(function(){
if($(this).scrollTop() > 100) {
$('logo_h logo_h__img').fadeOut('slow');
$('#logo-img img')
.css({'width':'184px','height':'33px'})
.attr('src','logo1.png');
}
if($(this).scrollTop() < 100) {
$('logo_h logo_h__img').fadeIn('fast');
$('#logo-img img')
.css({'width':'184px','height':'60px'})
.attr('src','logo2.png');
}
});
});
Filenames replaced for the sake of demonstration.
Thank you!
Thanks to help from #rlemon I have a script that works better, now implementing it is the task I am having trouble with!!
<!-- Logo Scroll -->
var img = document.querySelector('.logo_h__img img'); // get the element
img.dataset.orig = img.src; // using dataset is just being fancy. probably don't do this
document.addEventListener('scroll', function (e) { // add the event listener
if (document.body.scrollTop > 0) { // check the scroll position
img.src = img.dataset.scroll; // set the scroll image
} else {
img.src = img.dataset.orig; // set the original image back
}
});

How do I make a scroll to top button appear when a pre-determined part of the page appears?

I've got a scroll to top button I implemented via code that I got from one of the numerous examples out there. It works great. I changed the timing function for its appearance so that instead of appearing after 100 pixels it appears after 1340. I did this because there's some boxes on the right and I don't want the button to appear until they've been scrolled by and empty space thus appears for the button to fade in. The timing looked perfect -- the button appeared after what I figured was 1340 pixels from the top of the page.
However, I noticed that on a different (larger) screen the button didn't appear at the right time, but later. What I realized (if I gather correctly) was that the 1340 specification wasn't an absolute number of pixels from the top of the page, but was how many pixels had been scrolled through from the bottom of the browser window. For example, if I re-size the height of my browser window from, say, 1000 pixels to 400 pixels and reload the page, the button will appear 600 pixels too soon.
So my question is, is there a way to change my code so that the button appears only once a certain part of the page, measured from the top of the window, appears on screen?
Here's the javascript I'm currently using:
<script type="text/javascript">
$(document).ready(function () {
$(window).scroll(function () {
if ($(this).scrollTop() > 1340) {
$('#scrollup').fadeIn();
} else {
$('#scrollup').fadeOut();
}
});
$('#scrollup').click(function () {
$("html, body").animate({ scrollTop: 0 }, 500);
return false;
});
});
</script>
Thanks for any help.
Try this one--
<script type="text/javascript">
$(document).ready(function () {
ToggleScrollUp();
$(window).scroll(function () {
ToggleScrollUp();
});
$('#scrollup').click(function () {
$("html, body").animate({ scrollTop: 0 }, 500);
return false;
});
});
function ToggleScrollUp() {
if ($(".yourbox").offset().top < $(window).scrollTop() + $(window).height()) {
$('#scrollup').fadeIn();
} else {
$('#scrollup').fadeOut();
}
}
</script>
Check out this fiddle: http://jsfiddle.net/ro39dkaL/2/
Instead of using 1340 calculate the position of the bottom of the boxes instead, you can calculate the position on the fly so it's always accurate to the situation:
$(document).ready(function () {
var elem = $('#weblinks');
var bottom = $(elem).position().top+$(elem).outerHeight(true)
$(window).scroll(function () {
if ($(this).scrollTop() > bottom) {
$('#scrollup').fadeIn();
} else {
$('#scrollup').fadeOut();
}
});
$('#scrollup').click(function () {
$("html, body").animate({ scrollTop: 0 }, 500);
return false;
});
});
the 1340 specified is hard coded which wont be accurate in all cases.
A better solution is to find the height of the element w.r.t the browser window.
the jquery .offset() can be used.
var offset = $("#child").offset();
var fromTop = offset.top - $(window).scrollTop();
I made this fiddle and I use another way: as you can see, I placed a div with id scroll_toggle. When the user reaches this div (obviously you can remove the text, this is just a demonstration).
This is the fiddle: http://jsfiddle.net/afilini/7633pr0r/

Categories