Capture first visible div id while scrolling (viewport) - javascript

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

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

Toggle class when object visible in the viewport

I need a script which toggle a class when another class or section is visible in the viewport (during scrolling).
Here I have an script which works for precised distance from top, but can somebody help me to modify it for my needs?
$(window).scroll(function(){
if ($(this).scrollTop() > 50) {
$('#viewport').addClass('turn_on');
} else {
$('#viewport').removeClass('turn_on');
}
});
A couple of things. First the scroll event (as well as the resize event) fire multiple times. Traditionally, developers have used something called debouncing to limit the number of times a function fires. I've never got it to work correctly, so instead I check if a condition is met before continuing. You are basically doing this already.
var bool = false
$(window).on('scroll', function(){
if(!bool){
bool = true;
//fire the function and then turn bool back to false.
};
});
The next thing you need is to identify the element to add the class to. Let's say it has an id of foo.
var yOffset = $('#foo').offset().top;
From here, you'll need to compare the current vertical scroll position with that of the yOffset. You may also need to add the height of the element for when it scrolls out of frame.
var elHeight = $('#foo').height();
The element should be completely in frame with the $(window).scrollTop() equals the yOffset and out of frame when the $(window).scrollTop() is greater than yOffset + elHeight.
This is all assuming the element isn't in the frame to begin with. If it is, it will be trickier but it's a start.
Working fiddle
Try to add function that detect if element passed in argument is visible :
function isVisisble(elem){
return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}
$(window).scroll(function(){
if (isVisisble( $('your_element') ))
$('#viewport').addClass('turn_on');
} else {
$('#viewport').removeClass('turn_on');
}
});
Hope this helps.
Thx everyone for help.
Here I found the solution: LINK
And here is the modified script:
$(document).ready(function () {
var windowHeight = $(window).height(),
gridTop = windowHeight * 0.1,
gridBottom = windowHeight * 1;
$(window).on('scroll', function () {
$('.inner').each(function () {
var thisTop = $(this).offset().top - $(window).scrollTop();
if (thisTop > gridTop && (thisTop + $(this).height()) < gridBottom) {
$(this).addClass('on');
}
});
});
});

JQuery Add Class when bottom of div reaches top

I am trying to add a class when the bottom of a div reaches the top of the window, but am not sure of how to do it.
I have managed to add the class when the top of the div gets to the top of the window, but am not having much luck with the bottom of the div.
Code I am using:
$(document).ready(function() {
var menuLinksTop = $('.container').offset().top;
var menuLinks = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > menuLinksTop) {
$('header').addClass('black-links');
} else {
$('header').removeClass('black-links');
}
};
menuLinks();
$(window).scroll(function() {
menuLinks();
});
Any help is appreciated.
You should use javascript's getBoundingClientRect() method, watch $(window).scroll event, and look at element's rectangle, its bottom value will give you what you need (if it's negative, your element is all the way up)
$(window).scroll(function() {
console.log($("div.watch")[0].getBoundingClientRect());
if ($("div.watch")[0].getBoundingClientRect().bottom < 0)
alert ("i'm out :3");
});
see jsFiddle http://jsfiddle.net/ja5nnbwr/2/
Add the height of the div. Assuming it is the .container :
var menuLinksTop = $('.container').offset().top + $('.container').height();

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