I've got a script that will allow for snap scrolling when you move down but I can't get it to allow the user to scroll back upwards.
var items = $(".item");
var animating = false;
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
if ($(value).offset().top > $(window).scrollTop()) {
animating = true;
$('body').animate( { scrollTop: $(value).offset().top + 'px' }, 1000);
setTimeout(function() { animating = false; }, 500);
return false;
}
});
}, 50));
}
});
http://jsfiddle.net/kZY9R/77/
You have to do
var body = $("html, body");
and
$(body).stop().animate( { scrollTop: $(value).offset().top)}, 1000,'swing');
Chrome reading body and srolling, Firefox need html to do it
Check Working Fiddle
Related
I would need to show my div (footer-nav) on 2200 px after scrolling
& then hide it again on 2800 px.
All good with my code in the initial part,
so my element is shown after 2200px and hides when the mouse does not move for two seconds,
but I would like also to hide completely my div when reaching 2800px scroll.
Have a look at my snippet, would be great to trigger the event each time I scroll up or down the window:
$(window).scroll(function(event) {
function footer()
{
var scroll = $(window).scrollTop();
if(scroll > 2200)
{
$(".footer-nav").fadeIn("slow").addClass("show");
}
else
{
$(".footer-nav").fadeOut("slow").removeClass("show");
}
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
if ($('.footer-nav').is(':hover')) {
footer();
}
else
{
$(".footer-nav").fadeOut("slow");
}
}, 2000));
}
footer();});
Thanks in advance!
Try using the following code:
$(window).scroll(function(event) {
function footer()
{
var scroll = $(window).scrollTop();
if(scroll > 2200 && scroll < 2800) <-- this line
{
$(".footer-nav").fadeIn("slow").addClass("show");
}
else
{
$(".footer-nav").fadeOut("slow").removeClass("show");
}
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
if ($('.footer-nav').is(':hover')) {
footer();
}
else
{
$(".footer-nav").fadeOut("slow");
}
}, 2000));
}
footer();});
I'm currently working on implementing my own version of snap-scrolling using vanilla JavaScript, and while I've got it mostly working as of now, I'm having trouble handling the scroll events.
My HTML looks something like this:
<div class="container">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
<div id="item4"></div>
</div>
And my JS looks something like this:
var pos = 0;
var isScrolling = false;
var id = 1;
$(window).scroll(function() {
if (!isScrolling) {
isScrolling = true;
var curPos = $(this).scrollTop();
if (curPos > pos) {
// scrolling down
if (id < 4) {
id++;
$('html, body').animate({
scrollTop: $('#item' + id).offset().top
}, 500);
}
} else {
// scrolling up
if (id > 1) {
id--;
$('html, body').animate({
scrollTop: $('#item' + id).offset().top
}, 500);
}
}
isScrolling = false;
pos = curPos;
}
});
What currently happens is when I scroll down my mouse wheel, it will do the animation but will keep proceeding to the next divs because of the multiple scroll events being fired. How do I make it so that it only listens to the first event (whether it scrolls up or down)?
A hacky way is to use timer:
var pos = 0;
var isScrolling = false;
var id = 1;
var lastScrollTime = $.now();
$(window).scroll(function() {
if ((!isScrolling)&&((($.now()-lastScrollTime)>3000)) {
isScrolling = true;
var curPos = $(this).scrollTop();
if (curPos > pos) {
// scrolling down
if (id < 4) {
id++;
$('html, body').animate({
scrollTop: $('#item' + id).offset().top
}, 500);
}
} else {
// scrolling up
if (id > 1) {
id--;
$('html, body').animate({
scrollTop: $('#item' + id).offset().top
}, 500);
}
}
isScrolling = false;
pos = curPos;
lastScrollTime = $.now();
}
});
You can register one time listeners in jQuery using jQuery.one.
EDIT:
You can use the complete callback of jQuery.animate to stop/start responding to scroll events.
var isScrolling = false;
$(window).on('scroll', function () {
if (!isScrolling) {
isScrolling = true;
var curPos = $(this).scrollTop();
if (curPos > pos) {
// scrolling down
if (id < 4) {
id++;
$('html, body').animate({
scrollTop: $('#item' + id).offset().top
}, 500,function(){
isScrolling = false;
});
}
} else {
// scrolling up
if (id > 1) {
id--;
$('html, body').animate({
scrollTop: $('#item' + id).offset().top
}, 500,function(){
isScrolling = false;
});
}
}
pos = curPos;
}
});
There's no easy way to deal with what it is known as kinetic scrolling.
Browsers do not provide developers a proper way to distinguish the meaningful scrolling from the inertial ones.
However, there are some attempts out there that aims to solve this issue, such as Lethargy.
Not 100% ideal, but very close to it.
Other than that, you can take a look at libraries like fullPage.js where another attempt to solve the issue was made.
i am searching for a slider which should change the slides vertically on scroll.
This is the refrence Url : https://www.uber.com/ The Mobile slider
Please help me,i am trying to do this since7,8 hours.
this is the code i am trying to use.
$(document).ready(function() {
// var totalheight=$(window).height();
// $('.carosel-section').css('height',totalheight);
//Set each section's height equals to the window height
//$('.moveable').height($(window).height());
$('.moveable').first().addClass('active');
$('.carousel-wrap').on('mousewheel DOMMouseScroll', function (e) {
e.preventDefault();//prevent the default mousewheel scrolling
var active = $('.moveable.active');
var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;
if (delta < 0) {
//mousewheel down handler
next = active.next();
if (next.length) {
var timer = setTimeout(function () {
$('body, html').animate({
scrollTop: next.offset().top
}, 'fast');
// move the indicator 'active' class
next.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 100);
}
} else {
prev = active.prev();
if (prev.length) {
var timer = setTimeout(function () {
$('body, html').animate({
scrollTop: prev.offset().top
}, 'slow');
prev.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 800);
}
}
});
});
Have you tried looking at Parallax.js? I think that is what you are looking for. The examples on the main page should give you a quick start!
I have a navigation bar that repositions after scrolling down. It works with position:fixed, but while scrolling I want it to move up like all the other content that follow on the site . I the user stops scrolling it should reposition on top:
Heres a demo:
http://jsfiddle.net/gvjeyywa/7/
But I want it to be position:absolute (especially for the scrolling on the Ipad)
http://jsfiddle.net/gvjeyywa/5/
How do i let the JS overide my CSS? Here is my JS:
var isInAction = false;
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
if (!isInAction){
isInAction = true;
$( "#navigation" ).animate({
top: "-" + $("#navigation").innerHeight() + "px"
}).delay(1000).animate({
top: "0px"
}, 800, function() {
isInAction = false;
});
}
}
lastScrollTop = st;
});
In the first look i think it's impossible but after some tries this code was created.
I spent long time to write this code and use several techniques and hope to be helpful.
Maybe there are simpler solutions too !!
var bitFlag = false;
var lastScrollTop = 0;
var timeoutId;
$navigation = $("#navigation");
$(window).scroll(function (event) {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.innerHeight();
if (intWindowTop > lastScrollTop) {
if (!bitFlag) {
$navigation.css("position", "absolute").css("top", intWindowTop + "px");
bitFlag = true;
}
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function () {
if (intWindowTop > intElementBottom) {
intDelayTime = setTimeout(function () {
$navigation.animate({
top: intWindowTop + "px"
}, 800);
}, 500);
}
}, 100);
} else {
$navigation.css("position", "fixed").css("top", "0px");
bitFlag = false;
}
lastScrollTop = intWindowTop;
});
The }, 500); section control Delay time in milliseconds and the }, 800); section control the slide down animation speed.
Check JSFiddle Demo
I have an accordion feature that does not adjust the viewport to the top of the open element when it is clicked. View on mobile or small screen size to see what i am talking about: http://startyourlife.com/biz-training/
Here is an example of one that works: http://tympanus.net/Tutorials/FlexibleSlideToTopAccordion/
You will see that if you click it scrolls to the top of that element. Here is the javascript I currently have:
if (section_title.length) {
section_title.click(function () {
if ((!section.hasClass('active')) && (!running)) {
running = true;
var currentHeight, newHeight;
items.each(function () {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
}
});
if (item.length) {
item.addClass('active');
}
sections.each(function () {
if ($(this).hasClass('active')) {
currentHeight = $(this).find('.w-timeline-section-content').height();
$(this).find('.w-timeline-section-content').slideUp();
}
});
newHeight = section_content.height();
if (activeIndex < index) {
$('html').animate({
scrollTop: $('html').scrollTop() - currentHeight
});
}
section_content.slideDown(null, function () {
sections.each(function () {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
}
});
section.addClass('active');
activeIndex = index;
running = false;
});
}
});
}
Fixed it, add this right after the last line "running = false"
var target = $(section);
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}