I have a javascript that enables autorotating tabs on my website. my tabs are in the bottom of the page and by the moment when you reach this section almost the last tab is opened so the portfolio sort of starts not from the first item.
is there a way to enable this script only when the section with tabs scrolls into view?
the code snippet is here:
<script>
var Webflow = Webflow || [];
Webflow.push(function() {
var tabTimeout;
clearTimeout(tabTimeout);
tabLoop();
// define loop - cycle through all tabs
function tabLoop() {
tabTimeout = setTimeout(function() {
var $next = $('.tabs-menu').children('.w--current:first').next();
if ($next.length) {
$next.removeAttr("href").click(); // click resets timeout, so no need for interval
} else {
$('.tab-link:first').removeAttr("href").click();
}
}, 15000);
}
// reset timeout if a tab is clicked
$('.tab-link').click(function() {
clearTimeout(tabTimeout);
tabLoop();
});
});
</script>
Detect how much the user has scrolled from top to determine when to run the function.With JavaScript:
var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;With jQuery:
var scrollTop = $(window).scrollTop();
Compare scrollTop with the position of the parent element of your Tabs.Here is a method to get that, if you need to calculate it:
How can I get an object's absolute position on the page in Javascript?
Related
I'm trying to create a simple scroll effect where the page header hides when the page scrolls down and reappears on scroll up. The HTML:
<header class="siteHeader">...</header>
...is hidden by applying the CSS class "siteHeader--up."
I'm using jQuery. Here is my code:
$(function () {
var $siteHeader = $('.siteHeader');
var $window = $(window);
// to determine scroll direction. initializes to 0 on page load
var scrollReference = 0;
function fixedHeader () {
var scrollPosition = $window.scrollTop();
// if page is scrolling down, apply the CSS class
if (scrollPosition > scrollReference)
{
$siteHeader.addClass('siteHeader--up');
}
// otherwise, page is scrolling up. Remove the class
else
{
$siteHeader.removeClass('siteHeader--up');
}
// update reference point to equal where user stopped scrolling
scrollReference = scrollPosition
}
$window.scroll(function () {
fixedHeader();
});
});
This works fine for the most part. The problem is when I scroll down the page and then refresh the page. Somehow the scroll function is being triggered. The header will be visible for a moment and then hide (as though the page thinks it's being scrolled down). The function is being triggered on page load (confirmed with a console.log), but I don't understand why, because it's only supposed to fire on scroll.
Can someone help me understand what's going on and how I can prevent it?
Thanks!
That is the expected behavior. When the page is refreshed, the browser remembers the scroll position and it scrolls the page to that position, later on the scroll event is fired.
I think that this could be a workaround to solve your problem:
When the jQuery scroll event is fired you can get the timeStamp property and if this timeStamp is very close to the window.onload timeStamp, surely it can't be an event triggered by the user:
I've used a value of 50 milliseconds, test if it is sufficient, I think that it is.
var startTime = false;
$(function () {
var $siteHeader = $('.siteHeader');
var $window = $(window);
// to determine scroll direction. initializes to 0 on page load
var scrollReference = 0;
function fixedHeader () {
var scrollPosition = $window.scrollTop();
// if page is scrolling down, apply the CSS class
if (scrollPosition > scrollReference)
{
$siteHeader.addClass('siteHeader--up');
}
// otherwise, page is scrolling up. Remove the class
else
{
$siteHeader.removeClass('siteHeader--up');
}
// update reference point to equal where user stopped scrolling
scrollReference = scrollPosition
}
$window.on("load", function (evt) {
startTime = evt.timeStamp;
});
$window.on("scroll", function (evt) {
if(!startTime || evt.timeStamp - startTime < 50) return;
fixedHeader();
});
});
Try Loading the function on window load as well as in the scroll function:
$window.load(function(){
fixedHeader();
});
Or on document ready maybe:
$(document).ready(function () {
fixedHeader();
});
This should trigger and reset the values in the Variables you made and therefore determine whether to set the header to fixed or not, regardless of the scroll position.
Let me know if it works because i'm kinda curious too :)
I have a long list of items and when I clicked into each item and return to the main list, the scroll position was lost.
How can I return to the same exact scroll position using jQuery? Is there any easy way to do it?
$(document).ready(function() {
$('.update-button').click(function (){
sessionStorage.scrollPos = $(window).scrollTop();
console.log(sessionStorage.scrollPos);
});
});
var init = function () {
//get scroll position in session storage
$(window).scrollTop(sessionStorage.scrollPos || 0)
};
window.onload = init;
Above is what my code looks like. I tried to log the position and sessionStorage.scrollPos was 0. I am pretty sure I scrolled the page to somewhere.
Help is greatly appreciated.
You need to store value of scroll position in sessionStorage (or any storage) and re use it again on page load.
$(window).scroll(function () {
//set scroll position in session storage
sessionStorage.scrollPos = $(window).scrollTop();
});
var init = function () {
//get scroll position in session storage
$(window).scrollTop(sessionStorage.scrollPos || 0)
};
window.onload = init;
Just modifying #Rayon Answer if it doesn't work someone.
$("body").on("scroll", function () {
//set scroll position in session storage
sessionStorage.scrollPos = $(window).scrollTop();
});
var init = function () {
//get scroll position in session storage
$("body").scrollTop(sessionStorage.scrollPos || 0)
};
window.onload = init;
You can replace the $("body") with the top most element in your HTML. I am using framework7 mobile applicaiton and I need to use $(".page-content"). It worked for me.
No easy solution, but on the click event where the redirect takes place, get the current scroll position using
var scroll = $(window).scrollTop();
Then store the value of the scroll variable into the localstorage (cookies if localstorage is not available).
Then on page load look for the scroll position from local storage if available and if so move to that position.
this work for readmore article or hide article, for get current position height of readmore clicked.
#note: you need toggle button readmore and hide
let readhide = document.querySelectorAll('.read-hide');
let readmore = document.querySelectorAll('.read-more');
readmore.forEach((more,key) => {
let height, moreHeight;
window.addEventListener('scroll', function(event){
height = Math.floor(event.target.scrollingElement.scrollTop);
});
more.addEventListener('click', function(){
moreHeight = height;
});
readhide[key].addEventListener('click', function(){
window.scrollTo(0, moreHeight);
});
});
Return Text
Try This.
<button onclick="goBack()">Go Back</button>
function goBack() {
window.history.go(-1);
}
I'm currently trying to change my header logo when the user scrolls past the dark background to a lighter background. I got the add/remove class working, but right when the user loads the page the image doesn't show because it executes when the scroll is greater than 0 pixels scroll. How do I show the initial conditions from page load without the user having scrolled already?
$(function() {
var header = $(".logo");
var about = $(".angle").offset().top;;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= about) {
header.removeClass('lightLogo').addClass('darkLogo');
} else {
header.removeClass('darkLogo').addClass('lightLogo');
}
});
});
The simplest might be to just add the class initially, like so:
$(function() {
var header = $(".logo").addClass('lightLogo');
var about = $(".angle").offset().top;;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= about) {
header.removeClass('lightLogo').addClass('darkLogo');
} else {
header.removeClass('darkLogo').addClass('lightLogo');
}
});
});
Now the header will start out with .lightLogo at page load.
I want a nav to highlight (or something similar) once a user clicks on it AND when a user scrolls to the corresponding section.
However, on my computer when one clicks on any of the nav events after3, only nav event 3 changes. I'm guessing this is because after one clicks on 4 or 5, the scroll bar is already at the bottom of the page, so 4 and 5 never reach the top. The only div at the top is post 3, so my code highlights nav event 3 and ignores the click.
Is there any way I can fix this? Ive tried if statements (only highlight nav event if it's at the top AND the scrollbar isn't at the bottom or the top isn't the last item).
Here is a more accurate fiddle, using a fix below showing what I am talking about. The fix now highlights on scroll, but if you click option 5, it will not highlight.
$('.option').children('a').click(function() {
$('.option').css('background-color', '#CCCCCC;');
$(this).css('background-color', 'red');
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$(window).scrollTop(postLocation);
});
$(window).scroll(function() {
var scrollBar = $(this).scrollTop();
var allPosts = [];
var post = $('.content').offset();
var lastPost = allPosts.legnth-1
var windowHeight = $(window).height();
var bottomScroll = windowHeight-scrollBar;
$(".content").each(function(){
allPosts.push($(this).attr('id'));
});
i = 0;
for(i in allPosts){
var currentPost = "#"+allPosts[i];
var postPosition = $(currentPost).offset().top;
if (scrollBar >= postPosition){
$('.option').css('background-color', '#CCCCCC');
$('#nav'+allPosts[i]).css('background-color', 'red');
};
};
});
I think you've overdone your scroll() handler, to keep it simple you just needs to check if the scrollbar/scrollTop reaches the '.contents' offset top value but should not be greater than its offset().top plus its height().
$(window).scroll(function () {
var scrollBar = $(this).scrollTop();
$(".content").each(function (index) {
var elTop = $(this).offset().top;
var elHeight = $(this).height();
if (scrollBar >= elTop - 5 && scrollBar < elTop + elHeight) {
/* $(this) '.content' is the active on the vewport,
get its index to target the corresponding navigation '.option',
like this - $('.Nav li').eq(index)
*/
}
});
});
And you actually don't need to set $(window).scrollTop(postLocation); because of the default <a> tag anchoring on click, you can omit that one and it will work fine. However if you are looking to animate you need first to prevent this default behavior:
$('.option').children('a').click(function (e) {
e.preventDefault();
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$('html, body').animate({scrollTop:postLocation},'slow');
});
See the demo.
What you are trying to implement from scratch, although commendable, has already been done by the nice folks at Bootstrap. It is called a Scrollspy and all you need to do to implement it is include Bootstrap js and css (you also need jquery but you already have that) and make some minor changes to your html.
Scrollspy implementation steps.
And here is a demonstration. Notice only one line of js. :D
$('body').scrollspy({ target: '.navbar-example' });
I want to slide a DIV with contents out -- within a defined page area; within a long vertical 1 page website.
I have it setup with 6 DIV blocks;
Block 5 I have a CSS3 / jQuery animation wrapped in a DIV -- that I would like to SLIDE out into the page (from either left or right) with jQuery.
I'm thinking determining the point of slide from a defined anchor point; put within the the mark-up of the area that I'd like the DIV to slide into.
How could I write this;
..something like -- if anchor tag; SlideIn?
Something like;
slideLeftHide: function() {
return this.each(function() {
$(this).hide('slide', {direction: 'left'}, 1000);
});
http://jsfiddle.net/SZ8uH/2/
Try something like this:
var animInTriggeredAt = $("a#slidein").offset().top; //show when the anchor comes on stage
var animOutTriggeredAt = animInTriggeredAt + $(window).height(); //hide when it leaves the stage
var animActive = false;
// handle scroll event
$(window).scroll(checkScrollCues);
function checkScrollCues(){
var scrollY = $(window).scrollTop();
if (scrollY > animInTriggeredAt && scrollY < animOutTriggeredAt && !animActive){
animActive = true;
$("#myAnimatedDiv").show(); //put whatever animation code you want in here
} else if ((scrollY < animInTriggeredAt || scrollY > animOutTriggeredAt) && animActive){
animActive = false;
$("#myAnimatedDiv").hide(); //put whatever animation code you want in here
}
}