How to check if i am passing in anchor - javascript

I have a menu like bootstrap 3.0 (http://getbootstrap.com/getting-started/) which follows
the scroll down and up, but i'd like to have my menu with class "active" corresponding to the div and anchor in the current position of the page.
How can i do this?
this is responsible to follow the scroll
$(window).scroll(function () {
if ($(this).scrollTop() > 90) {
marginTop = ($(document).scrollTop() - scroll) + marginTop;
scroll = $(document).scrollTop();
$("#sideMenu").animate({
"margin-top": marginTop + "px"
}, {
duration: 0,
queue: false
});
}

I believe you're asking about the "scroll spy" feature. You need to determine if the user has scrolled to the content.
A quick example using jQuery would be to compare the $(document).scrollTop with the offset().top of the element you care about.
Here's one possible library for doing this

Related

jQuery Smooth Scroll to Top AND to Anchor by ID (with Offset)

this is an extension to a questions that was previously answered here: See Prevoius Question
I have a bit of jQuery that is adding BOTH a smooth scroll to top function, AND a smooth scroll to any anchor found on a page.
Now, I just need to add an offset to the anchor scroll (110px) to account for fixed headers, WITHOUT messing up the scroll to top function.
Here's the existing code:
// Add To Top Button + Smooth Scroll to Anchors functionality
jQuery(document).ready(function($){
// Scroll (in pixels) after which the "To Top" link is shown
var offset = 700,
//Scroll (in pixels) after which the "back to top" link opacity is reduced
offset_opacity = 1200,
//Duration of the top scrolling animation (in ms)
scroll_top_duration = 700,
//Get the "To Top" link
$back_to_top = $('.to-top');
//Visible or not "To Top" link
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $back_to_top.addClass('top-is-visible') : $back_to_top.removeClass('top-is-visible top-fade-out');
if( $(this).scrollTop() > offset_opacity ) {
$back_to_top.addClass('top-fade-out');
}
});
//Smooth scroll to top
$back_to_top.on('click', function(event) {
event.preventDefault();
targetedScroll();
});
// example of smooth scroll to h2#anchor-name
$('#some-button').on('click', function(event) {
event.preventDefault();
targetedScroll('anchor-name');
});
// bind smooth scroll to any anchor on the page
$('a[href^="#"]').on('click', function(event) {
event.preventDefault();
targetedScroll($(this).attr('href').substr(1));
});
// scrolling function
function targetedScroll(id) {
// scrollTop is either the top offset of the element whose id is passed, or 0
var scrollTop = id ? $('#' + id).offset().top : 0;
$('body,html').animate({
scrollTop: scrollTop,
}, scroll_top_duration);
}
});
Any time your're scrolling to an element, you have to scroll lower than the element by the height of the fixed navbar. Similarly, the first element on the page needs a margin or padding to offset by the height of the navbar.
Since both of these offsets are the same, you can set the offset for scrolling at the same time you set the offset for the first element. When you're scrolling to an element, subtract the offset from the height from the top. This will still work even when scrolling to the top.
jQuery(document).ready(function($) {
var offset = $("nav").height();
$("body").css("padding-top", offset + "px");
$('a[href^="#"]').click(function(event) {
event.preventDefault();
var scrollY = $(this.href).offset().top;
$('html, body').animate({
scrollTop: scrollY - offset
}, 2000);
});
});

Jquery: find element position from top + element height to activate addClass

Jquery beginner here.
I'm currently using the below script in order to find an element and then add/remove a class based on the scroll position from said element.
I'm trying to make my fixed navigation icon change colour when over the dark background.
Currently my code says find element 1 and then addClass to element 2 when the user scrolls 1000px after the element is found. It works but isn't ideal as the page is responsive and the sections change height.
You can see here, section 2 is the white section below the top section: http://leebuckle.co.uk/
Id like find the height of section 2 and then add the class once the user scrolls the height of section 2. So it would be +(section_2 height) rather than +1000px
Thanks in advance!
$(document).ready(function(){
var div = $("#section_2");
var pos = div.position();
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
if (windowpos >= (pos.top + 1000)) {
$( "#nav-icon span" ).addClass("black_menu");
}
else {
$( "#nav-icon span" ).removeClass("black_menu");
}
});
});
You can use offset from jQuery to get the position of an element from the top of the document.
So your line that has
if (windowpos >= (pos.top + 1000)) { ...
May look something like:
if (windowpos >= (div.offset().top)) { ...
Use jQuery's .offset() to get the the top position of your section2 + .height(), to get your section2's height dynamically.
if (windowpos >= (div.offset().top + div.height()))

Full page slider with native scrollbar

I am building a full page slider that keeps the native scrollbar and allows the user to either free scroll, use the mouse wheel or navigation dots (on the left) to switch to a slide.
Once the user is on the last slide and tries to scroll down further, the whole slider moves up to reveal a simple scrollable section. If the user scrolls down and then tries to go back up, then this new section moves out of the way again and returns the slider back into view.
Fiddle: http://jsfiddle.net/3odc8zmx/
The parts I'm struggling with:
Only the first two navigation dots work. The third one DOES WORK if you area looking at the first slide. But doesn't do anything, if you are on slide 2. Note: the purple one is a short-cut to the second section of the page and not related to the slider.
When moving to the last slide (via the dots, if you're on the first slide) it causes the code to make the whole slider move upwards as it sees this as the user has slid past the last slide as per the description above. I have tried to combat this using a variable called listen to stop the scroll event listening when using the showSlide method... but it seems to be true even though I set it to false, and only reset it to true again after the animation...
When scrolling down using the mouse wheel, I can get to the second section and back up, but not to the first third section. I'm wondering if I could use the showSlide method to better handle this instead of the current dirty next and prev functions I have implemented.
Note: If the user has free-scrolled, when they use the mouse-wheel, I want the slider to snap to the nearest slide to correct itself... Any suggestions for how I could do this?
Can anyone offer some help?
Here's the JS:
var listen = true;
function nextSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: $('#section1').scrollTop() + $(window).height()
});
}
function prevSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: -$('#section1').scrollTop() + $(window).height()
});
}
function showSlide(index)
{
var offset = $('#section1 div').eq(index).offset();
offset = offset.top;
if(offset){
listen = false;
$('.slide-dot').removeClass('active');
$('.slide-dot').eq(index).addClass('active');
$('#section1').stop(true,false).animate({
scrollTop: offset
}, 500, function(){
listen = true;
});
} else {
alert('error');
}
}
$(document).ready(function(){
var fullHeight = 0;
$('#section1 div').each(function(){
fullHeight = fullHeight + $(this).height();
});
var lastScrollTop1 = 0;
$('#section1').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
if( $('#section1').scrollTop() + $(window).height() == fullHeight) {
if(listen){
$('body').addClass('shifted');
}
}
}
lastScrollTop1 = st;
});
$('#section1').on('mousewheel', function(e){
e.preventDefault();
var st = $(this).scrollTop();
if (st > lastScrollTop1){
nextSlide();
} else {
prevSlide();
}
});
var lastScrollTop2 = 0;
$('#section2').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
} else {
if( st == 0 ){
$('body').removeClass('shifted');
}
}
lastScrollTop1 = st;
});
$('.slide-dots').css({'margin-top':-$('.slide-dots').height() / 2});
$('.slide-dot').first().addClass('active');
$(document).on('click', '.slide-dot', function(e){
e.preventDefault();
showSlide( $(this).index() );
});
$(document).on('click', '.slide-dot-fake', function(e){
e.preventDefault();
$('body').addClass('shifted');
});
});
And for those wondering why I'm not using something like fullPage.js, it's because it can't handle the way I want to transition between the two areas and have two scrollbars (one for each area).
You can use:
e.originalEvent.wheelDelta
instead of:
st > lastScrollTop1
in the mousewheel event for your third problem to check if the user has scrolled up or down. And also change the +/- in prevSlide. I used dm4web's fiddle for your first problem. And I used:
scrollTop: offset - 1
instead of:
scrollTop: offset
for your second problem, because when the scroll reaches to the last pixel of the third element, it automatically goes to the next section, so 1 pixel is enough for it not to.
Here's the fiddle: http://jsfiddle.net/3odc8zmx/3/
As suggested by #chdltest, you could do it by using fullPage.js.
Here's an example. Go to the last section.
Code used for the example:
Javascript
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
scrollOverflow: true,
scrollBar: true,
afterLoad: function (anchor, index) {
//hiding the main scroll bar
if (index == 4) {
$('body, html').css('overflow', 'hidden');
}
//showing the main scroll bar
if (index == 3) {
$('body, html').css('overflow', 'visible');
}
}
});
CSS (in case you prefer to use the normal style for it)
/* Normal style scroll bar
* --------------------------------------- */
.slimScrollBar {
display: none !important;
}
.fp-scrollable {
overflow: auto !important;
}
Advantages of using fullPage.js instead to your own code:
Strongly tested in different devices and browsers. (IE, Opera, Safari, Chrome, Firefox..)
Prevent problems with trackpads, Apple laptops trackpads or Apple Magic Mouse.
Old browser's compatibility, such as IE 8, Opera 12...
Touch devices compatibility (IE Windows Phone, Android, Apple iOS, touch desktops...)
It provides many other useful options and callbacks.

Onscroll top of page: defining end of the page

I'm using the following javascript for the top of page logo/section before the footer here:
<div id="townEnd">InsideTown</div>
<script>
$(document).ready(function(){
// hide #townEnd first
$("#townEnd").hide();
// fade in #townEnd
$(function () {
$(window).scroll(function () {
if ($(this).scrollTop() > 1000) {
$('#townEnd').fadeIn();
} else {
$('#townEnd').fadeOut();
}
});
// scroll body to 0px on click
$('#townEnd a').click(function () {
$('body,html').animate({
scrollTop: 0
}, 800);
return false;
});
});
});
</script>
How would I calculate when the logo should fadein at the end of the page? I just used 1000 as an example. It only seems to work when I scroll really fast too.
First, you should just use this.scrollTop instead of $(this).scrollTop() - it might not look like much to you, but it is a HUGE thing.
On the same path, you can use this.scrollHeight to get the height of the scrollable area. Subtract this.innerHeight to get the maximum scroll position, then subtract about 30 pixels to give yourself some padding.
if( this.scrollTop < this.scrollHeight - this.innerHeight - 30)
You should also have a boolean to keep track of the state of the element, maybe isfadedin, which you update. Then, only call fadeIn and fadeOut if the state changes. This will save a LOT of processing time!
Vanilla JS is awesome :p

Stop DIV scrolling once it reaches the footer (another DIV)

I have a "back to top" button that appears when the user scrolls down the page.
With some help I have managed to implement these functions in the code below:
fade in at certain point after scrolling down, animated scroll back to top and animated scrolling to all href="#" links of the page.
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 800, 'swing', function () {
window.location.hash = target;
});
});
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() > 300) {
b.fadeIn();
console.log("fadding in")
}
else {
b.fadeOut();
}
});
});
Here is a working exsample: http://jsfiddle.net/q8DUC/8/
My problem is that the button scrolls into the footer of the page...
Basically the "back to top" should stop 30px above the "footer" DIV.
But I can't find a way to accomplish that. I've looked around but haven't found anything that worked with the existing code.
Thanks for any help or suggestions!
UPDATE:
Got a bit further: http://jsfiddle.net/q8DUC/20/
Just don't know how I can avoid the jumping of the button!
Is there a way to stick the button to the bottom instead the top:0???
As always THANKS for every suggestion or help!
I think you could get the location of the footer and add it to your conditional, which checks if the button should be displayed:
// dynamically get the position of the footer
var FOOTER_POSITION = someNumber;
// i THINK something like var FOOTER_POSITION = $('#T4').position().top; could work
if (300 < $win.scrollTop() && $win.scrollTop() < FOOTER_POSITION) {
Sorry, I read your question wrong, since you are using fixed positioning for your button you could implement something like:
get the height of the footer + 30px
Get a location of the footer in relation to the document, based on your fiddle ~2000px (FOOTER_START)
if the location of the top of the window is > 300 AND it is greater than (FOOTER_START) change #back-top bottom property to height of your footer

Categories

Resources