I have a survey page divided into sections. As the user scrolls, each section's header sticks to the top of the screen until the next section is reached. I was able to do it for the first and second section but I am not sure how to do it for the third one. There must be a better way to do this.
Here is my code and a jsfiddle
Thank you
var s = $("#block2 .question-title-block");
var pos = s.position();
$(window).scroll(function() {
var windowpos = $(window).scrollTop();
if ($(this).scrollTop() > 404) {
$('#block1 .question-title-block').addClass("sticky");
if (windowpos >= pos.top) {
$('#block2 .question-title-block').addClass("sticky");
$('#block1 .question-title-block').removeClass("sticky");
}
else{
$('#block2 .question-title-block').removeClass("sticky");
}
}
else{
$('#block1 .question-title-block').removeClass("sticky");
$('#block2 .question-title-block').removeClass("sticky");
}
})
If you want it to be applied to as many elements as you want, don't use them individually, use their class. Here is what you can do:
var titleBlocks = $(".question-title-block");
$(window).scroll(function() {
var windowpos = $(window).scrollTop();
titleBlocks.each(function(){
$(this).toggleClass('sticky', $(this).parent().offset().top <= windowpos);
});
});
JS Fiddle Demo
try this (allows for any number of question blocks):
var containers = $('.question-block-container');
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
containers.each(function () {
var container = $(this),
title = container.find('.question-title'),
contOffsetTop = container.offset().top,
conOffsetBottom = contOffsetTop + container.outerHeight() + 60; // 60 is margin bottom
if (windowpos >= contOffsetTop && windowpos <= conOffsetBottom) {
if (!title.hasClass("sticky")) {
title.addClass("sticky");
}
} else if (title.hasClass("sticky")) {
title.removeClass("sticky");
}
});
});
Example
Related
Here is the Jsfiddle i am working on
https://jsfiddle.net/farooqshad/jbdczk10/10/
Basically i want to add a class on scroll to specific div and then remove that class .
Here is my javascript
var YourDiv = $(".mainwrapper");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
console.log(scroll);
if (scroll >= YourDiv.offset().top - 10) {
YourDiv.addClass('fixed');
console.log("fixed");
} else {
YourDiv.removeClass('fixed');
console.log("Not Fixed");
}
});
farooq try this solution
var YourDiv = $(".mainwrapper");
var foo=$(".footer1")
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= YourDiv.offset().top - 10 && scroll<=foo.offset().top - 10) {
YourDiv.addClass('fixed');
}
else
{
YourDiv.removeClass('fixed');
}
});
and let me know if don't works
this is fiddle
Added this code to my sticky element using position:sticky
var $sticky = $('.grid-container .sticky'),
$stickyTo = $('.grid-container .stickyTo'),
stickyToTop = $stickyTo.offset().top,
stickyToBottom = stickyToTop + $stickyTo.outerHeight();
$(window).on('scroll', function() {
var scroll = $(window).scrollTop(),
stickyTop = $sticky.offset().top,
stickyBottom = $sticky.offset().top + $sticky.outerHeight();
if (stickyBottom >= stickyToBottom) {
if (scroll < stickyTop) {
//$sticky.addClass('fixed').removeClass('abs');
} else {
//$sticky.addClass('abs');
}
} else if (scroll > stickyToTop) {
$sticky.addClass('stuck');
} else if (scroll < stickyToTop) {
$sticky.removeClass('stuck');
}
});
and I have two sticky elements see image attached but when I scroll to the first section it adds a class "stuck" on the second section, how can I make that only on that section jquery is triggered and not affect the second/other section unless scrolled on
Here is My FIDDLE
Because $sticky in your case is a jQuery collection with two elements in it you have to use .each() loop to check each element separately. Then you probably don't need $stickyTo, because you have to check for each 'sticky' element's own .parent(). Something like this:
var $sticky = $('.grid-container .sticky'),
$(window).on('scroll', function() {
var scroll = $(window).scrollTop()
$sticky.each(function(){
const $this = $(this)
const stickyTop = $this.offset().top,
const stickyBottom = stickyTop + $sticky.outerHeight();
const $stickyTo = $this.parent()
const stickyToTop = $stickyTo.offset().top,
const stickyToBottom = stickyToTop + $stickyTo.outerHeight();
if (stickyBottom >= stickyToBottom) {
if (scroll < stickyTop) {
//$sticky.addClass('fixed').removeClass('abs');
} else {
//$sticky.addClass('abs');
}
} else if (scroll > stickyToTop) {
$sticky.addClass('stuck');
} else if (scroll < stickyToTop) {
$sticky.removeClass('stuck');
}
})
});
Please note though, this function is not really optimized. It would be better to use native javascript during the scroll. Or even better check native CSS position: sticky.
I'm trying to create sticky headers that when you scroll to a div the head state becomes fixed and stays in view, when the div has come to an end and scrolls out of view I want the title to then become absolute and stay at the bottom of its parent.
I've got the initial part working only I'm struggling on adding the 'absolute' class...
https://jsfiddle.net/yw313vf2/1/
function fixTitle() {
$('.service-pane').each(function() {
var $this = $(this);
var offset = $this.offset().top;
var scrollTop = $(window).scrollTop();
if (scrollTop > offset) {
$this.addClass('fixed');
} else {
$this.removeClass('fixed');
}
});
}
$(window).scroll(fixTitle);
So I had to run another check within the function to see if when scrolled the end of my div had reached the top of the window and if so add an additional class...
function fixTitle() {
$('.service-pane').each(function() {
var $this = $(this);
var offset = $this.offset().top - 50;
var scrollTop = $(window).scrollTop();
if (scrollTop > offset) {
$this.addClass('fixed');
if ($this[0].getBoundingClientRect().bottom < $('.manifesto').height() + 50) {
$this.addClass('absolute');
} else {
$this.removeClass('absolute');
}
} else {
$this.removeClass('fixed');
}
});
}
This is my current solution to check if a specific div reaches the top of the page, which i got from here https://stackoverflow.com/a/5279537/4671165
document.addEventListener("scroll", Scroll, false);
function Scroll() {
var top = $('.element').offset().top - $(document).scrollTop();
if (top < 150){
var textvariable = $('.text').text();
}
}
But i want this to do something each time a different div reaches the top of the page, therefore i currently have
var top1 = $('.element1').offset().top - $(document).scrollTop();
var top2 = $('.element2').offset().top - $(document).scrollTop();
var top3 = $('.element3').offset().top - $(document).scrollTop();
if (top1 < 150 && top2 > 150){
var textvariable = $('.text1').text();
}
if (top1 < 150 && top2 < 150 && top3 > 250){
var textvariable = $(.text2').text();
}
if (top2 < 150 && top3 < 250){
var textvariable = $(.text3').text();
}
However, this doesn't seem the most effective way but i can't figure out what is. Especially since i have more elements then just 3 in the project. So i am looking for a more effective way.
I put this together using ES6. I believe this should work. It's been a while since I've used getBoundingClientRect() though.
var divs = document.querySelectAll('div');
document.addEventListener("scroll", Scroll, false);
function Scroll() {
divs.forEach((memo,index) => {
let divTop = memo.getBoundingClientRect().top;
if (divTop <= 0) {
var textvariable = $('.text' + index).text();
});
}
Hope this helps. It should be easier to use and it has a lot of bugs already fixed for you. It's a 1.82 kb file so there's not really much useless stuff into it if added.
I found a jquery solution
function ScrollStart() {
var scrolled = $(this).scrollTop();
/*filter current element at the top with a certain class & give it active class*/
$('.step').removeClass('activetext').filter(function() {
return scrolled <= $(this).offset().top + $(this).height() - 50 && scrolled >= $(this).offset().top - 50;
}).addClass('activetext');
/* make exclusion for first element */
var boven = $('.first').offset().top - $(document).scrollTop();
if (boven > 0){
$('.first').addClass('activetext');
}
/*make exclusion for last element*/
var bottom = $('.last').offset().top - ($('.last').height()/5) - $(document).scrollTop();
if (bottom < 150){
$('.step').removeClass('activetext')
$('.last').addClass('activetext');
}
else{
$('.last').removeClass('activetext')
}
/* give variable 'text' the text of the active class & append it */
var text = $('.activetext .headertekst').text();
$('.dropbtn').empty();
$('.dropbtn').append(text);
$('.dropbtn').append('<img src="images/downarrow.svg" galleryimg="no"></img>');
}
I'd like to add a class to an element when a user first scrolls away from the top of the page. If the user then scrolls back up and hits the top of the page I'd like that class removed.
Use of jQuery in the solution is fine.
try
$(window).scroll(function() {
$("id or class").removeClass("active");
var scroll = $(window).scrollTop();
if (scroll <= 500) {
$("#one").addClass("active");
}
else if (scroll <= 1000) {
$("#tow").addClass("active");
}
else {
$("#three").addClass("active");
}
}
So here is the solution you're looking for. Just customize it with your div tags.
$(document).ready(function () {
$(window).scroll(function(){
// get the height of #wrap
var h = $('#top').height();
var y = $(window).scrollTop();
if( y > (h*.25) ){
$("#sidef").fadeIn(1100);
} else {
$('#sidef').fadeOut(75);
}
});
});
var notAdded = true;
$(window).scroll(function(){
if( $(this).scrollTop() == 0){
$(elem).removeClass('classname');
notAdded = true;
}
else if(notAdded){
$(elem).addClass('classname');
notAdded = false;
}
});