I want to show a Top-Bar, when the user scrolled back to top of the site.
So e.g. the user scrolls down for a minimum of a 300-400px and then when he scrolls back up again to maybe around 100px (left to the top of the site) the bar should toggle / show up.
Thanks for your help! :)
You can add an event listener to document to check when a user scrolls down the page. Once they hit a preset breakpoint, you can remove a hidden class from your navbar element, like so:
var breakpoint = 400;
var navbar = $('.nav-bar');
$(document).scroll(function(){
if($(this).scrollTop() >= breakpoint) {
navbar.removeClass('hidden', 500);
}
});
If your navbar is fixed, you can also check a boolean variable to see if the user has scrolled past the breakpoint, and then set it to true. If they scroll up past the breakpoint, you can then show the navbar, like so:
var breakpoint = 400;
var scrolledPastBreakpoint = false;
var navbar = $('.nav-bar');
$(document).scroll(function(){
if($(this).scrollTop() >= breakpoint) {
scrolledPastBreakpoint = true;
};
if($(this).scrollTop() < breakpoint && scrolledPastBreakpoint) {
navbar.removeClass('hidden', 500);
};
});
Related
In my html I've got a div that changes its class when the user scrolls past it (and the div becomes out of view), such that when the user scrolls back up the page the class is changed.
I would like to have that div class reverted to original the second time the user scrolls back up, but just can't figure out a way to do so. I'm trying to find a way for it to work in such a way that the effect repeats and the class alternates every time it comes back into view.
I'm doing this with two scripts at the moment. The first one works and changes the class of the div when the user scrolls back up:
<script>
$(function() {
var scroll1 = $(window).scrollTop(); // how many pixels have been scrolled
var os1 = $('#div1').offset().top; // pixels to top of div1
var ht1 = $('#div1').height(); // height of div1 in pixels
if (scroll > os1 + ht1) {
$('#div1').removeClass('english').addClass('japanese');
}
});
</script>
But the second one doesn't seem to do anything at all:
<script>
$(function() {
var scroll2 = $(window).scrollTop();
var os2 = $('#div1').offset().top;
var ht2 = $('#div1').height();
var class1 = document.getElementsByClassName('japanese')[0].className;
if (scroll > os1 + ht1 && class1 == 'japanese') {
$('#div1').removeClass('japanese').addClass('english');
}
});
</script>
I guess this is happening because you have the same conditions in both of the functions.
For the second condition use this instead
if(scroll < os1 + ht1)
I have two navigation one is on the top and another is in content. I try to make the second sub menu as sticky when it reached to the top menu not the very top offset of browser. But i failed to make it sticky when it scrolled to top. Also how can I add class on on menu item when active 'href' scrolling.
JSfiddle Here
JS Code
$(document).ready(function() {
var $filter = $('.denpen-menu');
var $filterSpacer = $('<div />', {
"class": "filter-drop-spacer",
"height": $filter.outerHeight()
});
if ($filter.size())
{
$(window).scroll(function ()
{
if (!$filter.hasClass('navbar-fixed') && $(window).scrollTop() > $filter.offset().top)
{
$filter.before($filterSpacer);
$filter.addClass("navbar-fixed");
}
else if ($filter.hasClass('navbar-fixed') && $(window).scrollTop() < $filterSpacer.offset().top)
{
$filter.removeClass("navbar-fixed");
$filterSpacer.remove();
}
});
}
});
First we should fetch the starting position of our subNavand store it as "startingPoint"
var startingPoint = $('.stuckMenu').offset().top - 48;
Notice the - 48 part, that's about the height of our main navigation, and a bit less just so it feels better when they touch.
The key part of the logic is this part here:
if (!subNav.hasClass('navbar-fixed') && $(window).scrollTop() > startingPoint)
{
$filter.addClass("navbar-fixed");
}
else if(subNav.hasClass('navbar-fixed') && $(window).scrollTop() < startingPoint)
{
$filter.removeClass("navbar-fixed");
}
Where we ask:
Is our subNav sticky yet? Is the top of the window touching it currently?
Ok its not sticky yet but the window touched it, make it sticky - fixed.
Ok so our subNav is sticky, is the top of the window above the original position of our subNav?
It is above? Ok I do not want it to be sticky any more, so we'll just remove the class.
Check out the example here
I have a div called #menu which I want to display when I scroll past the element #section3, if I scroll up past that element again, I want #menu to disappear
How would I code this?
Maybe something like this?
scrolled = "no"
$(window).scroll(function(){
scr = $("body").scrollTop();
if (scr > 100 && scrolled == "no"){
$("#menu").css({"display:block"})
displayed = "yes"
}
if (displayed == "yes" && scrolled = "yes"){
$("#menu").css({"display:none"})
}
});
The above assumes that #section3 is 100 pixels down the page. If you do not know where its going to be on the page then you could use the method outlined here:
Trigger event when user scroll to specific element - with jQuery
With jQuery you can get the scroll position with $("body").scrollTop();.
Expanding on what #Ned Hulton said, I recommend comparing the scroll position to the top of a "container element" (or 'row') in your page like this:
if ($('body').scrollTop() > $('#someRow').offset().top){
//do something
}
That way you can account for your container appearing at a variable distance down the page (which will come in handy for mobile browsing or cases where your text wraps to additional lines)
I just whipped this up in jsfiddle
https://jsfiddle.net/rb56j0yu/
it uses jQuery, and checks the scroll position against the target div. Css sets the menu as position: fixed, and defaults to hidden.
$(window).scroll(function(){
var yPos = $("body").scrollTop();
var yCheck = $("#c3").position().top;
if (yPos > yCheck && !$("#menu").is(":visible"))
{
$("#menu").show();
}
if (yPos <= yCheck && $("#menu").is(":visible"))
{
$("#menu").hide();
}
});
First, get your #section3 top offset and height. Which will be used as the threshold whether #section3 is actually on the window screen.
var top = $('#section3').offset().top;
var bot = topOffset + $('#section3').height();
Then, detect it on your scroll event.
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop();
if (scrollTop >= top && scrollTop <= bot) {
// #section3 is within the screen.
$('#menu').show();
}
else {
// #section3 is out of screen.
$('#menu').hide();
}
});
This is a common use case, I wrote following code:
// what does "Auto Header" mean, goto https://www.yahoo.com/
// scroll down and you will see the purple part auto fixed to top,
// while when scroll up, it restores and does not be fixed.
// 1. multiple auto header elements handled
// 2. dynamically create/remove elements issue handled
// 3. no unnecessary dom operation, high performance
// usage: just add 'class="auto-header"' to any element you want to auto header
// suggest set each auto-header element specific width and height
// do not guarantee it works when resize or scroll left/right
$(document).ready(function() {
var rawTops = [],
rawLefts = [],
rawStyles = [],
$locations = [], // record next sibling so that element easily find where to restore
fixed = []; // mark whether this element is fixed
$(".auto-header").each(function() {
var $this = $(this),
offset = $this.offset();
rawTops.push(offset.top);
rawLefts.push(offset.left);
rawStyles.push($this.attr("style"));
$locations.push($this.siblings().eq($this.index()));
fixed.push(false);
});
$(window).on("scroll", function() {
$(".auto-header").each(function(i, e) {
if(!fixed[i] && $(window).scrollTop() > rawTops[i]) {
var $te = $(this).clone(true);
$(this).remove();
$locations[i].before($te);
$te.css({
"position": "fixed",
"top": 0,
"left": rawLefts[i],
"z-index": 100
});
fixed[i] = true;
} else if(fixed[i] && $(window).scrollTop() < rawTops[i]) {
$(this).removeAttr("style").attr("style", rawStyles[i]);
fixed[i] = false;
}
});
});
});
The general idea to the site i am designing is to scroll through a set of menu items horizontally and incrementally underneath a static div that will magnify(increase dimensions and pt size) the contents of a menu items. I don't really need help with the magnify portion because i think it's as simple as adding a mag class to any of the menuItem divs that go underneath the static div. I have been messing with this for a few weeks and the code I have for incrementally scrolling, so far, is this:
$(document).ready(function () {
currentScrollPos = $('#scrollableDiv').scrollTop(120); //sets default scroll pos
/*The incrementScroll function is passed arguments currentScrollPos and UserScroll which are variables that i have initiated earlier in the program, and then initiates a for loop.
-The first statement sets up the variables: nextScrollPos as equal to the currentScrollPos(which by default is 120px) plus 240px(the distance to next menuItem), prevScrollPos as equal to the currentScrollPos(which by default is 120px) minus 240px(the distance to next menuItem).
-The second Statement checks to see if the user has scrolled using var userScroll
-The third statement sets: var CurrentScroll equal to the new scroll position and var userScroll to false*/
function incrementScroll(currentScrollPos, userScroll) {
for (var nextScrollPos = parseInt(currentScrollPos + 240, 10),
prevScrollPos = parseInt(currentScrollPos - 240, 10); //end first statement
userScroll == 'true'; console.log('dude'), //end second statement and begining of third
currentScrollPos = scrollTop(), userScroll = 'false') {
if (scrollTop() < currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(prevScrollPos, 10))
}, 200);
console.log('scrolln up')
} else if (scrollTop() > currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(nextScrollPos, 10))
}, 200);
console.log('scrolln down')//fire when
}
}
}
$('#scrollableDiv').scroll(function () {
userScroll = 'true';
_.debounce(incrementScroll, 200); //controls the amount of times the incrementScroll function is called
console.log('straight scrolln')
});
});
I have found a variety of solutions that are nigh close: such as a plugin that snaps to the next or previous div horizontally demo, another solution that also snaps and is based on setTimeout demo, but nothing that nails incrementally scrolling through divs. I also found a way to control the rate at which a user may scroll through the menuItems using debounce which is included in the above code.
The console.logs inside the loop do not fire when I demo the code in jsfiddle which leads me to believe the problem lies within the loop. I'm a noob though so it could be in syntax or anywhere else in the code for that matter. Also in the second demo, i have provided the css for the horizontal static div, but the moment I put it in my html it keeps the js from working.
I would like to write the code instead of using a plugin and any help would be appreciated! Also, thank you ahead of time!
Try this fiddle. Menu container height is 960px to show 4 menu items. "Zoom" div is positioned absolutely at top. When you scroll mouse over this div, menu items shifts to top/bottom. I had to add additional div to bottom to be able to scroll to last 3 menu items. JS code:
jQuery(document).ready(function($){
var current = 0;
var menu = $('.menu-container').scrollTop(0);
var items = menu.find('.menu-item');
var zoom = $('.zoom');
function isVerticalScroll(event){
var e = event.originalEvent;
if (e.axis && e.axis === e.HORIZONTAL_AXIS)
return false;
if (e.wheelDeltaX)
return false;
return true;
}
function handleMouseScroll(event){
if(isVerticalScroll(event)){
var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
current += (delta > 0 ? 1 : -1);
if(current < 0)
current = 0;
if(current >= items.length){
current = items.length - 1;
}
menu.stop().animate({
"scrollTop": current * 240
}, 300);
items.removeClass('current').eq(current).addClass('current');
event && event.preventDefault();
return false;
}
}
zoom.on({
"MozMousePixelScroll": handleMouseScroll,
"mousewheel": handleMouseScroll
});
});
Hope it will help.
so I have this javascript:
$(window).scroll(function () {
if ($(window).scrollTop() > 0 && !document.contains(document.getElementById('toTop'))) {
var top = '<div id="toTop" onclick="tTop()"></div>';
$('body').append(top);
}
});
function tTop() {
$('html,body').scrollTop(0);
}
$(window).scroll(function () {
if (document.contains(document.getElementById('toTop')) && $(window).scrollTop() == 0) {
$('div').remove('#toTop');
}
});
It works just fine if the page is loaded while the scroll bar is at the top; however when I refresh the page while the scroll bar is at the bottom, the page will still scroll up, but the scroll stays at the bottom. Can anyone tell me how to fix this?
when I refresh the page while the scroll bar is at the bottom, the
page will still scroll up, but the scroll stays at the bottom
Maybe I'm misreading this, but are you concerned that the buttons are staying at the bottom of the page? Or $(window).scrollTop() is set to 0 after you click the button, after a page refresh?
Regardless, I would separate the scroll callback to another method, checking if the element exists (I used a button for an example instead of a div)
function scrollCallback() {
if ($(window).scrollTop() > 0) {
if ($('body').has('#toTop').length == false) {
var top = '<input type="button" id="toTop" onclick="tTop();" value="top" />';
$('body').append(top);
}
}
else {
// Removes the button if the scroll is at the top of the page.
$('body #toTop').remove();
}
}
Then on your page load, call the scrollCallback, and set your scroll to also use the scroll back:
$(function() {
// Execute it when you load the page.
scrollCallback();
$(window).scroll(scrollCallback);
});