jQuery offset().top not working properly - javascript

I am trying to get a div to stick once it is scrolled out of view.
var jQ = jQuery.noConflict();
jQ(document).ready(function() {
var win = jQ(window);
var navTop = jQ('#navbar').offset().top;
win.scroll(function() {
jQ('#navbar').toggleClass('sticky', win.scrollTop() > navTop);
});
});
The problem is that with this code, navTop is not calculated correctly. If I calculate navTop in the scroll function it works as expected but with a horrible flickering effect which I assume is due to recalculating the value many times.
Why does it not calculate the value correctly after document is loaded?

The fix I used for this problem was to fire another scroll event once to calculate the navTop variable and it works ok now.
Final Code:
var jQ = jQuery.noConflict();
jQ(document).ready(function() {
var win = jQ(window);
var navTop;
jQ(document).one("scroll", function() {
navTop = jQ('#header').offset().top;
});
win.scroll(function() {
jQ('#navbar').toggleClass('sticky', win.scrollTop() > navTop);
});
});

Related

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");
}
});

jQuery scroll event switching back and forth between if/else

I have a column that I want to stick to the top of the page, but once it gets to the point of sticking any further scrolling causes it to jump back and forth between having the added class and not.
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#stick-me').offset().top;
if (window_top >= div_top) {
$('#stick-me').addClass('stick');
} else {
$('#stick-me').removeClass('stick');
}
}
$(function () {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
My intuition tells me it's an issue with the conditional statements, but I'm not sure how else I can structure it. Thanks in advance!
You don't need to add/remove the class as such, simply toggle class. Without seeing your CSS and other JS conflicts all I can do is show you a working example.
DEMO http://jsfiddle.net/tbdbyxvu/
var $window = $(window),
$stickyEl = $('#the-sticky-div'),
elTop = $stickyEl.offset().top;
$window.scroll(function() {
$stickyEl.toggleClass('sticky', $window.scrollTop() > elTop);
});
the #stick-me element is getting moved when your class 'stick' is applied (as you would want).
When your function runs a second time, div_top is now a new (larger) number and your if statement (which proved true the first time) now proves false and removes the class.
In short, your class is being added and removed over and over again.
I would suggest storing #stick-me's original location on page load in a variable startingPoint outside of sticky_relocate, then adding/removing the class when scrollTop is greater than startingPoint.
function sticky_relocate() {
var window_top = $(window).scrollTop();
if (window_top >= startingPoint) {
$('#stick-me').addClass('stick');
} else {
$('#stick-me').removeClass('stick');
}
}
$(function () {
var startingPoint = $('#stick-me').offset().top;
$(window).scroll(sticky_relocate);
});

Need to trigger an event as footer comes into view

I have a deep page with a deep footer
I want to use some jQuery to trigger an event when the top of the footer comes into view
I have looked and tried using
var scrollTop = jQuery (window).scrollTop();
but it just gives the position when you load, and it doesn't change as you scroll
Any ideas please
You can use my script on this answer: Pause and play video when in viewport
Fiddle: http://jsfiddle.net/pwhjk232/
$(document).ready(function() {
var inner = $(".inner");
var elementPosTop = inner.position().top;
var viewportHeight = $(window).height();
$(window).on('scroll', function() {
var scrollPos = $(window).scrollTop();
var elementFromTop = elementPosTop - scrollPos;
if (elementFromTop > 0 && elementFromTop < elementPosTop + viewportHeight) {
inner.addClass("active");
} else {
inner.removeClass("active");
}
});
})

Show id when div is halfway up

So I know how to actually get ids and classes and do the basics but I'm not sure how to do this:
"When the user scrolls down, the title of the post that takes up half the screen should be shown."
The setup is supposed to look something like this...
Any ideas?
You need to use JS and I used jQuery to do a simple prototype
It's all about listening to the scroll event and dealing with the offset of the elements from top you need to add a simple condition for the heights but now it's just working fine
$(window).scroll(function(){
var scrolledTop = $(this).scrollTop();
console.log(scrolledTop);
$(".blog").each(function(){
if($(this).offset().top < scrolledTop)
{
$('#blogname').html($(this).html());
}
});
});
Check out this http://jsfiddle.net/GkrCU/2/
I hope this can help :)
Here is my answer
$(window).scroll(function () {
var windowheight = $(this).scrollTop();
$(".blog").each(function () {
var sc = $(this).offset().top;
var id = $(this).attr('id');
if (sc < windowheight) {
$("#blogname span").html(id)
}
});
});
http://jsfiddle.net/GkrCU/1/

Scrolling to Div IDs with Jquery

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.

Categories