Scrolling to Div IDs with Jquery - javascript

Due to css properties my scrolling to div tags has too much margin-top. So I see jquery as the best solution to get this fixed.
I'm not sure why this isn't working, I'm very new to Js and Jquery. Any help us greatly appreciated.
Here is a quick look at Js. I found that when your div ids are in containers to change the ('html, body') to ('container)
Here is my jsfiddle
jQuery(document).ready(function($){
var prevScrollTop = 0;
var $scrollDiv = jQuery('div#container');
var $currentDiv = $scrollDiv.children('div:first-child');
var $sectionid = 1;
var $numsections = 5;
$scrollDiv.scroll(function(eventObj)
{
var curScrollTop = $scrollDiv.scrollTop();
if (prevScrollTop < curScrollTop)
{
// Scrolling down:
if ($sectionid+1 > $numsections) {
console.log("End Panel Reached");
}
else {
$currentDiv = $currentDiv.next().scrollTo();
console.log("down");
console.log($currentDiv);
$sectionid=$sectionid+1;
console.log($currentDiv.attr('id'));
var divid =$currentDiv.attr('id');
jQuery('#container').animate({scrollTop:jQuery('#'+divid).position().top}, 'slow');
}
}
else if (prevScrollTop > curScrollTop)
{
// Scrolling up:
if ($sectionid-1 == 0) {
console.log("Top Panel Reached");
}
else {
$currentDiv = $currentDiv.prev().scrollTo();
console.log("up");
console.log($currentDiv);
$sectionid=$sectionid-1;
var divid =$currentDiv.attr('id');
jQuery('html, body').animate({scrollTop:jQuery('#'+divid).position().top}, 'slow');
}
}
prevScrollTop = curScrollTop;
});
});

I'm not entirely sure what you want but scrolling to a <div> with jQuery is simpler than your code.
For example this code replaces the automatic jumping behaviour of anchors with smoother scrolling:
$(document).ready(function(e){
$('.side-nav').on('click', 'a', function (e) {
var $this = $(this);
var top = $($this.attr('href')).offset().top;
$('html, body').stop().animate({
scrollTop: top
}, 'slow');
e.preventDefault();
});
});
You can of course adjust the top variable by adding or removing from it like:
var top = $($this.attr('href')).offset().top - 10;
I have also made a fiddle from it (on top of your HTML): http://jsfiddle.net/Qn5hG/8/
If this doesn't help you or your question is something different, please clarify it!
EDIT:
Problems with your fiddle:
jQuery is not referenced
You don't need jQuery(document).ready() if the jQuery framework is selected with "onLoad". Remove the first and last line of your JavaScript.
There is no div#container in your HTML so it's no reason to check where it is scrolled. And the scroll event will never fire on it.
Your HTML is invalid. There are a lot of unclosed elements and random tags at the end. Make sure it's valid.
It's very hard to figure out what your fiddle is supposed to do.

Related

jQuery Navbar transition on scroll. How to adjust specific point of transition

In a site I'm building I'm trying to make the navbar change color when I scroll. However, I don't want it to change colors as soon as I start scrolling. I want it at a specified point (once I scroll past my jumbotron).
So far, I've only been able to make it work by scrolling from the top. I'm not quite skilled enough to figure out how to do it past a specific point on my page. I would greatly appreciate some guidance on this.
jQuery script
$(function () {
$(document).scroll(function () {
var $nav = $(".fixed-top");
$nav.toggleClass('scrolled', $(this).scrollTop() > $nav.height());
});
});
Thanks for any help or guidance!
There are a lot of ways you can do it.
one way could be done with pure javascript.
change changeColorValue that represents the scroll bar value according to your needs.
Here is my suggestion:
LIVE DEMO
JavaScript:
var changeColorValue = 50;
window.addEventListener("scroll", scrollAnim);
function scrollAnim () {
var val = getScrollVal();
if(val > changeColorValue)
{
document.getElementById('mynav').style.backgroundColor = 'red';
}
else
{
document.getElementById('mynav').style.backgroundColor = '#333';
}
}
function getScrollVal()
{
var val = $(document).scrollTop();
return val;
}

can't change z index with javascript

I'm trying to change the Z index of an image according to the scroll position,currently in chrome (but it should be working on all broswers).
anyway, it's not working on chrome, unless I get into inspection mode and I don't understand why it's only working in inspection mode?
this is the script:
$( window ).scroll(function() {
var scrollTop = $(window).scrollTop();
if ($(this).scrollTop()>700) {
document.getElementById("back-ground-image").style.zIndex = "-9";
console.log("-9");
} else {
document.getElementById("back-ground-image").style.zIndex = "-19";
console.log("-19");
}
});
Problem
What you need is $(document) not $(window).
By default, you scroll the $(document), not the $(window).
However, when you open your Chrome DevTools, the $(window) is not being scrolled which is why your code works.
To fix the issue, change $(window).scroll() to $(document).scroll() and $(window).scrollTop() to $(document).scrollTop()
Improvements
1. Use jQuery functions
Also, if you're already using jQuery, why not use jQuery selectors and .css():
$("#back-ground-image").css('zIndex', '-9')
instead of
document.getElementById("back-ground-image").style.zIndex = "-9";
2. Use DRY code
(Don't Repeat Yourself)
If you follow recommendation #1, why not set $("#back-ground-image") to a variable instead of repeating it twice.
$(document).scroll(function() {
var scrollTop = $(document).scrollTop(),
$bkImg = $("#back-ground-image");
if ($(this).scrollTop() > 700) {
$bkImg.css('zIndex', '-9');
console.log("-9");
} else {
$bkImg.css('zIndex', '-19');
console.log("-19");
}
});
Otherwise, you could use:
$(document).scroll(function() {
var scrollTop = $(document).scrollTop(),
background = document.getElementById("back-ground-image");
if ($(this).scrollTop()>700) {
background.style.zIndex = "-9";
console.log("-9");
} else {
background.style.zIndex = "-19";
console.log("-19");
}
});

How to keep class active when scrolling with javascript?

I need help figuring out what is going on with my javascript. I have some code that is supposed to make the nav links have an active class when you are on that part of the page, but it's only sort of working for a couple links and it also flickers as you scroll rather than staying active the whole time you're on that part of the page. See the JSFiddle for an example https://jsfiddle.net/7szpuqsr/ -- if you scroll slowly you can see how "home" becomes active for a moment. I am trying to get each link to have the active class when you click it and also while you are on that entire part of the page.
I also have a javascript sticky nav bar and smooth scrolling working so I don't know if possibly any of that is getting in the way? Thanks in advance for help.
Here's the Javascript I'm trying to use for the active class:
var sections = $('section')
, nav = $('nav')
, nav_height = nav.outerHeight();
$(window).on('scroll', function () {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top - nav_height,
bottom = top + $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find('a').removeClass('active');
sections.removeClass('active');
$(this).addClass('active');
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
}
});
});
nav.find('a').on('click', function () {
var $el = $(this)
, id = $el.attr('href');
$('html, body').animate({
scrollTop: $(id).offset().top - nav_height
}, 500);
return false;
});
Something like this? I couldn't reproduce the flickering visually on my machine but I can see the class being removed/added constantly on scroll
https://jsfiddle.net/7szpuqsr/1/
Main changes, I added a class to your sections, you have too many sections but with the way your code is meant to work, it's much easier to add a class to the sections, example below
<section id="home" class="section">
var sections = $('.section') to get the section class
updated this part of the js to check for active class
if (cur_pos >= top && cur_pos <= bottom) {
if(!$(this).hasClass("active")) {
nav.find('a').removeClass('active');
sections.removeClass('active');
$(this).addClass('active');
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
}
}
You can also cache the $(this) into a variable inside of the section loop like
var $this = $(this);
then just use $this for the rest of the loop
here is the doc for hasClass https://api.jquery.com/hasclass/

Previous and Next Scrolling to next post

I've been struggling with this all day.. I've got a couple of posts, each have a next and previous button. The idea is for each post and its next and previous buttons, to scroll the window to the next post or previous post. I have tried using the each() function and unfortunately, its tricky to get working.
This is the jQuery so far:
var scrollTo = function(element) {
$('html, body').animate({
scrollTop: element.offset().top
}, 100);
}
function prev_next_scrolling() {
var articles = $("article.post"),
counter = 0;
articles.each( function() {
var articles = $(this);
$('.next-btn', articles).click( function() {
scrollTo($('article.post').eq(counter + 1));
});
$('.prev-btn', articles).click( function() {
scrollTo($('article.post').eq(counter - 1));
});
counter++;
});
}
prev_next_scrolling();
And this is the HTML:
<article class="post">
<h2>Post Title</h2>
<p>Post description</p>
Previous
Next
</article>
Here is the jsfiddle link for you guys to have a looksie!
http://jsfiddle.net/casacoda/2zM3Q/
Any help will be much appreciated! Thanks in advance guys!
The problem with your code is that counter is defined in the scope of prev_next_scrolling(), so all the functions run by the each() method will use the very same instance of the variable. Each time you increase counter, that will happen for all places where it has been used.
You can fix that by introducing a variable local to the function that handles a specific element -- or actually, you don't have to because jQuery already gives you exacly that as an optional parameter in the each() callable. See http://api.jquery.com/each/
So here's the correct code (http://jsfiddle.net/2zM3Q/3/):
var scrollTo = function(element) {
$('html, body').animate({
scrollTop: element.offset().top
}, 100);
}
function prev_next_scrolling() {
var articles = $("article.post"),
counter = 0;
articles.each( function(index) {
var articles = $(this);
$('.next-btn', articles).click( function() {
scrollTo($('article.post').eq(index + 1));
});
$('.prev-btn', articles).click( function() {
scrollTo($('article.post').eq(index - 1));
});
counter++;
});
}
prev_next_scrolling();
There are still some problems: It doesn't check whether it already is the first/last post and if it's already at the end of the page it obviously won't scroll any further, creating the illusion of a "broken" link (because nothing seems to be happening after clicking it.)
I've updated the fiddle to address all your concerns in the comments
Updated Working Fiddle
I got it working without all your each code, just navigating the dom.
Let me know if you have questions about the Fiddle provided. Basically this takes advantage of your current structure being known, it finds the next ARTICLE using parent().next() and then finds that ARTICLEs h2. It then uses the H2s vertical offset position to scroll to it. Same for previous links but using parent().prev()
$(document).on('click', '.next-btn', function(){
// find the next anchor
var nextAnchor = $(this).closest('article').next().find('h2')
$('html,body').animate({scrollTop: nextAnchor.offset().top},'slow');
});
$(document).on('click', '.prev-btn', function(){
// find the previous anchor
var prevAnchor = $(this).closest('article').prev().find('h2')
$('html,body').animate({scrollTop: prevAnchor.offset().top},'slow');
});
One thing to note, if the H2 in question is already visible on the screen it will not scroll UP to anything, only if its off screen will it scroll UP to it. Scroll down will always move the screen if needed.

Capture first visible div id while scrolling (viewport)

I have this page:
I want to capture on which div I am while I'm scrolling.
I know If I use:
if( $(document).scrollTop() > $('#div1').position().top) {
console.log('Div1')
}
...it will capture the div1 but instead of using this code for every div I want to set 1 snippet for all divs
Something like:
var a = // The div i am at
if( $(document).scrollTop() > $(a).position().top) {
console.log($(a).attr('id'))
}
I am looking something like the viewport: http://www.appelsiini.net/projects/viewport/3x2.html
Can I achieve that without a plugin, simply 2-3 lines?
Here's a nice way to do it. You may want to optimize the '<=' with a pixel offset to improve user experience and move the div selector ($divs) outside the callback to increase performance. Have a look at my fiddle: http://jsfiddle.net/brentmn/CmpEt/
$(window).scroll(function() {
var winTop = $(this).scrollTop();
var $divs = $('div');
var top = $.grep($divs, function(item) {
return $(item).position().top <= winTop;
});
});
Just throw it into a loop.
var list = [];
$("div").each(function(index) {
if( $(document).scrollTop() > $(this).position().top)
list.push($(this));
});
alert(list);
The list will than have every div that is within your viewport.
I'd suggest using the jQuery Inview plugin:
https://github.com/protonet/jquery.inview
Well maintained Plugin that detects whatever content is in the viewer currently, enabling you to bind functions to an inview event. So as soon as your div is in view you could fire off all the relevant functions you wanted and then again when it has left the users view. Would be great for your needs.
$(window).scroll(function () {
$("#privacyContent div").each(function () {
var bottomOffset = ($(this).offset().top + $(this).height());
console.log("Botom=",bottomOffset ,"Win= ", $(window).scrollTop());
if (bottomOffset > $(window).scrollTop()) {
$("#menu a").removeClass("active");
// console.log("Div is= ",$(this).attr('id'));
$("#menu a[href='#" + $(this).attr('id') + "']").addClass("active");
$(".b").removeClass("fsActive");
var div = $(this);
div.find(".b").addClass("fsActive");
return false;
}
});
});
I do it like this it works fine it detect all div id

Categories