I have a sidebar that continually checks the users scrollposition and depending on their position, changes the background image of a specific image on a sidebar when needed to indicate which section on the page is being viewed. When viewing this sidebar locally, I see the sidebar flicker.
After uploading it to my site and viewing it there, the flickering stopped, but just in case, I wanted to know if anyone knows why and how to stop it. My website where the sidebar can be viewed in action (it's the sidebar on the left with number 1,2,3, and 4) is here. My code is below.
$(document).scroll(function() {
var greenheight = document.getElementById('welcome_logo').offsetHeight;
var redheight = document.getElementById('slideins').offsetHeight;
var blueheight = document.getElementById('section_overview').offsetHeight;
var yellowheight = document.getElementById('howsiteworks').offsetHeight;
if($(window).scrollTop() > redheight){
if (navslide != 2) {
if($(window).scrollTop() < greenheight+redheight){
$('#side2').css("background-image", "url(images/sidebar/side2_over.fw.png)");
$('#side1').css("background-image", "url(images/sidebar/side1.fw.png)");
$('#side3').css("background-image", "url(images/sidebar/side3.fw.png)");
$('#side4').css("background-image", "url(images/sidebar/side4.fw.png)");
var navslide = 2
}
}
}
if($(window).scrollTop() < redheight)
if (navslide != 1) {
{
$('#side1').css("background-image", "url(images/sidebar/side1_over.fw.png)");
$('#side2').css("background-image", "url(images/sidebar/side2.fw.png)");
$('#side3').css("background-image", "url(images/sidebar/side3.fw.png)");
$('#side4').css("background-image", "url(images/sidebar/side4.fw.png)");
var navslide = 1
}
}
if($(window).scrollTop() > redheight+greenheight){
if (navslide!=3) {
if($(window).scrollTop() < greenheight+redheight+blueheight){
$('#side3').css("background-image", "url(images/sidebar/side3_over.fw.png)");
$('#side1').css("background-image", "url(images/sidebar/side1.fw.png)");
$('#side2').css("background-image", "url(images/sidebar/side2.fw.png)");
$('#side4').css("background-image", "url(images/sidebar/side4.fw.png)");
var navslide = 3
}
}
}
if($(window).scrollTop() > redheight+greenheight+blueheight){
if (navslide!=4) {
if($(window).scrollTop() < greenheight+redheight+blueheight+yellowheight){
$('#side4').css("background-image", "url(images/sidebar/side4_over.fw.png)");
$('#side1').css("background-image", "url(images/sidebar/side1.fw.png)");
$('#side2').css("background-image", "url(images/sidebar/side2.fw.png)");
$('#side3').css("background-image", "url(images/sidebar/side3.fw.png)");
var navslide = 4
}
}
}
});
It's because you're using different images for every possible scenario (e.g. 1, 2, 3, 4, 1-over, 2-over, 3-over, 4-over, etc). The over images aren't loaded in the browser when scrolling. In other words, as you'r scrolling, your CSS goes, "I need to switch images. Let me remove the current image first... [image disappears] OK... now let me download this other image. Aaaaaaand, done! [image reappears]" This is the "blinking" that you're seeing.
Two basic techniques you can apply to mitigate this are:
Pre-loading the relevant images:
http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
http://css-tricks.com/snippets/jquery/image-preloader/
Use sprites (a single image instead of 8)
http://css-tricks.com/css-sprites/
http://www.smashingmagazine.com/2009/04/27/the-mystery-of-css-sprites-techniques-tools-and-tutorials/
Hope this helps.
Related
I have looked around to see if this has been covered, but no dice.
I'm building a website using HTML5, CSS3 (+ animations), bootstrap, Vanilla JS and jQuery. The behavior I'm looking to induce for the site is one where a user visits a landing page and the scroll bar is situated at the top. Then, upon scrolling down past a certain point, a completely different screen takes over.
Here's the (maybe) tricky part:
I want for a visitor to be able to scroll all the way up on this 2nd screen as high as the scrollbar can go. Only once the scroll bar is at the top and they try try to scroll up past the top of the current window, that the original, first screen comes back in to play (while still persisting the progress they made on the 2nd screen if they decide to scroll back down).
Negative scrollTop/browser/window heights to trigger an event in which a user can navigate between pages using a maxed out up-top scrollbar? (& should I use a framework?) Much appreciated!
You could duplicate elements while scrolling,
I made a plunker to give you an idea
jQDocument.on("scroll", () => {
if(jQDocument.scrollTop() < 200) {
//Duplicate elements on top while scrolling up
let topScreen = detectTopScreen()
let indexTopScreen = getIndex(topScreen)
let screenIndexToDuplicate
if(indexTopScreen > 0) {
screenIndexToDuplicate = indexTopScreen - 1
} else {
screenIndexToDuplicate = maxIndex
}
let screenToPrepend = originalLoopDiv.children().eq(screenIndexToDuplicate).clone()
loopDiv.prepend(screenToPrepend)
if(loopDiv.children().length > 6) {
loopDiv.children().eq(loopDiv.children().length - 1).remove()
}
}
if(jQDocument.scrollTop() + jQWindow.outerHeight() > jQBody.outerHeight() - 200) {
//Duplicate elements on bottom while scrolling down
let bottomScreen = detectBottomScreen()
let indexBottomScreen = getIndex(bottomScreen)
let screenIndexToDuplicate
if(indexBottomScreen < maxIndex) {
screenIndexToDuplicate = indexBottomScreen + 1
} else {
screenIndexToDuplicate = 0
}
let screenToAppend = originalLoopDiv.children().eq(screenIndexToDuplicate).clone()
loopDiv.append(screenToAppend)
if(loopDiv.children().length > 6) {
loopDiv.children().eq(0).remove()
}
}
})
I currently have a nav bar within my header that I would like to become fixed after the user scrolls past a certain element. I would also like to achieve the same animation effect as seen at http://pixelmatters.com
When I say 'same' I mean using the same nav bar/header element that I'm using at the top, rather than using a duplicate somewhere else in my document.
I've tried to achieve he result with my own code shown below. I've also included a jsFiddle link of my current setup.
jQuery
var bottomElement = $('.dividerWrap').offset().top + $('.dividerWrap').height();
$(window).on('scoll', function() {
var stop = Math.round($(window).scrollTop());
if (stop > bottomElement) {
$('.header').addClass('isFixed');
} else {
$('.header').removeClass('isFixed');
}
});
https://jsfiddle.net/npfc8wsx/1/
I answered something like that few days ago. please take a look at this code:
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
var scrollToVid = $('#test').offset().top
console.log(scrollTop); //see window scroll distance //
console.log(scrollToVid); //see scroll to div offest//
if ($(window).scrollTop() >= scrollToVid) {
alert('You reached to the video!');
}
});
jSFiddle
Main Question
now for you some code must change:
$(window).scroll(function () {
var scrollToElem = $('.dividerWrap').offset().top
if ($(window).scrollTop() >= scrollToElem) {
$('.header').addClass('isFixed');
} else {
$('.header').removeClass('isFixed');
}
});
I have 2 divs on my webpage. first div is "#pattern" (red one), and second on is "#projets".(blue one)
when use scrolls for the first time, the window scrolls automaticaly to the the second div "#projets". I'm using jquery scroll-To plugin.
it works nice, even if when the users scroll with a large amount of scroll there could be on offset from the "#projets" div... If someone has an idea to correct this would be nice, but that's not my main trouble...
Now i'm trying to scroll back to the top of the page ("#pattern" div) as soon as "#pattern" div reappears when scrolling, the red one. so basically it should be as soon as the offset from the top of my screen of my div "#projets" is supperior to 1.
I've tried so many solutions without results, using flags, multiple conditions... it can be the same kind of thing as on this page, but user should be abble to scroll freely inside the page, not scrolling from hash to hash :
http://www.thepetedesign.com/demos/onepage_scroll_demo.html
here is my html :
<div id="pattern"></div>
<div id="projets"></div>
my css :
#pattern {
height:300px;
width: 100%;
background-color:red
}
#projets {
height:800px;
width: 100%;
background-color:blue
}
and my jquery :
var flag=0 ;
$(window).on('scroll',function(){
var top_projets_position = $("#projets").offset().top - $(window).scrollTop();
if((flag==0) && $(window).scrollTop()>1){
$(window).scrollTo('#projets', 500);
flag=1;
}
if($(window).scrollTop()==0){
flag=0;
}
});
here is jsfiddle :
http://jsfiddle.net/jdf9q0sv/
hope someone can help me with this, I can't figure out what I'm doing wrong, maybe a wrong method ! thanks
It looks like you need to track 3 things:
The scroll direction occurs.
The area you are currently viewing.
If scroll animation is currently happening (we need to wait until it's done, or problems will occur).
http://jsfiddle.net/vx69t5Lt/
var prev_scroll = 0; // <-- to determine direction of scrolling
var current_view ="#pattern"; // <-- to determine what element we are viewing
var allowed = true; // <-- to prevent scrolling confusion during animation
var top_projets_position = $("#projets").offset().top + 1;
$(window).on('scroll',function(){
var current_scroll = $(window).scrollTop();
if(current_scroll < top_projets_position && current_view=="#projets" && current_scroll < prev_scroll){
scrollToTarget("#pattern");
}
if($(window).height() + current_scroll > top_projets_position && current_view=="#pattern" && current_scroll > prev_scroll){
scrollToTarget("#projets");
}
prev_scroll = current_scroll;
});
function scrollToTarget(selector){
if(allowed){
allowed = false;
$(window).scrollTo(selector, {
'duration':500,
'onAfter': function(){ allowed = true; current_view = selector;}
});
}
}
This is just a quick solution based on your original code. A better solution would be to do something more Object Oriented (OOP) and track values in an object. Perhaps take an array of elements on object creation, grab all the boundaries and use the boundaries in your scroll handler to determine when to scroll to the next div.
I'm currently trying to change my header logo when the user scrolls past the dark background to a lighter background. I got the add/remove class working, but right when the user loads the page the image doesn't show because it executes when the scroll is greater than 0 pixels scroll. How do I show the initial conditions from page load without the user having scrolled already?
$(function() {
var header = $(".logo");
var about = $(".angle").offset().top;;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= about) {
header.removeClass('lightLogo').addClass('darkLogo');
} else {
header.removeClass('darkLogo').addClass('lightLogo');
}
});
});
The simplest might be to just add the class initially, like so:
$(function() {
var header = $(".logo").addClass('lightLogo');
var about = $(".angle").offset().top;;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= about) {
header.removeClass('lightLogo').addClass('darkLogo');
} else {
header.removeClass('darkLogo').addClass('lightLogo');
}
});
});
Now the header will start out with .lightLogo at page load.
I would like to make it so when user scrolls down and reaches a certain div, say #float, set that div to margin-top: 50px and position fixed, and if user scrolls back up undo those changes. It's hard to understand I know ))) If you go to this page and pay your attention to sidebar once scrolling up and down you will see what I mean.
As you scroll down 2nd advertisement scrolls with a page too.
How would I achieve same functionality with jQuery/CSS?
This is a way of doing it in jQuery.
This code is provided for example purposes only; there are almost certainly a handful of regularly-maintained jQuery plugins that will do this thing for you - check GitHub or DailyJS.
$(window).scroll(function() {
var styledDiv = $('#styledDiv'),
targetScroll = $('#float').position().top,
currentScroll = $('html').scrollTop() || $('body').scrollTop();
styledDiv.toggleClass('fixedPos', currentScroll >= targetScroll);
});
Here is a simple JSFiddle of the above in action.
Edit: Have now refactored this code to a more elegant solution.
Edit 2: Following an email I received about a question, I've updated the code above so that it also works in Firefox. As $('body').scrollTop() will not work in Firefox (See comments on the jQuery API page), we need to check both the html and body elements.
This is the relevant jQuery/JavaScript code use on that site.
if (window.XMLHttpRequest) {
var topGagStay = $("top-gag-stay");
var isLoggedIn = $("profile-menu") ? true : false;
var sidebarAdsTop = 1061 - 545;
var signupBtnOffset = 60;
var dockPos = 72;
if (!isLoggedIn && !GAG.isReadOnly()) {
sidebarAdsTop += signupBtnOffset
}
if (formMessageShown) {
sidebarAdsTop += formMessageOffset
}
if (topGagStay) {
if (document.documentElement.scrollTop > sidebarAdsTop || self.pageYOffset > sidebarAdsTop) {
if (topGagStay.style.position != "fixed") {
topGagStay.style.position = "fixed";
topGagStay.style.top = dockPos + "px"
}
} else {
if (document.documentElement.scrollTop < sidebarAdsTop || self.pageYOffset < sidebarAdsTop) {
topGagStay.style.position = "";
topGagStay.style.top = ""
}
}
}
}
Thank FireBug and http://jsbeautifier.org/ for the code (and 9GAG, of course).
I have tried the above answer by beardtwizzle and it worked fine. Also made it work for the case when the page is scrolled upto the bottom of the page.
see the working demo/tutorial here