mouseWheel stops scrolling until I move mouse elsewhere Chrome - jQuery - javascript

I have a section based on scrolling. The idea is that you scroll you travel from 1 to 2 to 3 then you progress to the next section.
All works fine except 1 glitch - if mouse does not move and only the wheel is used, after the 1,2,3 is over, the scrolling stops working and does not allow to scroll further downwards and same happens for the upwards.
I've checked and found some articles explaining that it can be a Chrome issue because it works fine for me on Edge, Safari. I see this issue only in Chrome.
Any ideas would be appreciated.
Here is my fiddle where you can see it in action.
jQuery(document).ready(function($){
var $container = $('#scrolling-container'),
top = 0,
lastScrollTop = 0,
proceedFlag = true;
var scroller = function(event) {
top += $container.height() * (($(this).scrollTop() > top) ? 1 : -1);
var firstBarItem = jQuery(".bf-content:first-child");
if (top == 0 || top <= lastScrollTop){
// upscroll code
var previousBarItem = jQuery(".bf-content.active").prev();
if(previousBarItem.length && previousBarItem.hasClass('bf-content')){
jQuery(".bf-content.active").removeClass('active');
previousBarItem.addClass('active');
}else{
jQuery('html, body').stop().animate({'scrollTop': jQuery(".top-section").offset().top}, 300, 'swing', function(){
var $target = jQuery(".top-section");
$target.focus();
});
}
} else {
// downscroll code
var nextBarItem = jQuery(".bf-content.active").next();
if(nextBarItem.length && nextBarItem.hasClass('bf-content')){
jQuery(".bf-content.active").removeClass('active');
nextBarItem.addClass('active');
}else{
jQuery('html, body').animate({'scrollTop': jQuery(".bottom-section").offset().top}, 150, 'swing', function(){
var $target = jQuery(".bottom-section");
$target.focus();
});
}
}
lastScrollTop = top;
if(proceedFlag){
$container.stop().animate({scrollTop: top}, 300, 'swing', function() {
$(this).clearQueue().one("scroll", function() {
$(this).one("scroll", scroller);
jQuery('html, body').stop().animate({'scrollTop': jQuery("#scrolling-container").offset().top}, 300, 'swing');
jQuery("#scrolling-container").focus();
});
});
return;
}
}
$container.one("scroll", scroller);
});

Related

jQuery scrollTop() returns wrong offset on scroll-direction change

I'm trying to get the correct scroll direction via jQuery's "scroll" event.
For this, I'm using the solution here: https://stackoverflow.com/a/4326907/8407840
However, if I change the direction of my scroll, the offset returned by scrollTop is incorrect on the first time. This results in the following behavior:
Wheel down -> down
Wheel down -> down
Wheel up -> down
Wheel up -> up
Wheel down -> up
Wheel down -> down
... and so on, I think you get it.
var ACTIVE_SECTION = null;
var ANIMATION_DURATION = 700;
$(document).ready(function() {
ACTIVE_SECTION = $("section:first-of-type").get(0);
var prevPosition = $(window).scrollTop();
$(window).on("scroll", function() {
doScrollingStuff(prevPosition);
});
});
function doScrollingStuff(prevPosition) {
var ctPosition = $(window).scrollTop();
var nextSection = ACTIVE_SECTION;
// Remove and re-append event, to prevent it from firing too often.
$(window).off("scroll");
setTimeout(function() {
$(window).on("scroll", function() {
doScrollingStuff(prevPosition);
});
}, ANIMATION_DURATION + 100);
// Determine scroll direction and target the next section
if(ctPosition < prevPosition) {
console.log("up");
nextSection = $(ACTIVE_SECTION).prev("section").get(0);
} else if(ctPosition > prevPosition) {
console.log("down");
nextSection = $(ACTIVE_SECTION).next("section").get(0);
}
// If a next section exists: Scroll to it!
if(typeof nextSection != 'undefined') {
var offset = $(nextSection).offset();
$("body, html").animate({
scrollTop: offset.top
}, ANIMATION_DURATION);
ACTIVE_SECTION = nextSection;
} else {
nextSection = ACTIVE_SECTION;
}
console.log(ACTIVE_SECTION);
prevPosition = ctPosition;
}
section {
width:100%;
height:100vh;
padding:60px;
box-sizing:border-box;
}
section:nth-child(1) { background:#13F399; }
section:nth-child(2) { background:#14FD43; }
section:nth-child(3) { background:#4EE61E; }
section:nth-child(4) { background:#BEFD14; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="sect1">Section 1</section>
<section id="sect2">Section 2</section>
<section id="sect3">Section 3</section>
<section id="sect4">Section 4</section>
Here's a pen, where you can see my implementation: https://codepen.io/EigenDerArtige/pen/aVEyxd
I am trying to accomplish an autoscroll to the next or previous section, whenever the user scrolls or swipes up/down... Therefore I only fire the "scroll"-event once every second, to prevent multiple scrolljacks all happening at once... However the above behavior seems to result in the user being scrolled to the wrong section.
I've been trying for a couple of hours now to get it working, but to no avail. Help is greatly appreciated!
The problem lies in the assignment prevPosition = ctPosition.
Each time the scroll handler runs, var ctPosition = $(window).scrollTop(); is good for determining scroll direction, however it's not the value that should be rememberad as prevPosition.
prevPosition needs to be $(window).scrollTop() as measured after the animation has completed.
Try this :
$(document).ready(function() {
var ANIMATION_DURATION = 700;
var ACTIVE_SECTION = $("section:first-of-type").eq(0);
var prevPosition = $(window).scrollTop();
$(window).on("scroll", doScrollingStuff);
function doScrollingStuff(e) {
$(window).off("scroll");
var ctPosition = $(window).scrollTop();
var nextSection = (ctPosition < prevPosition) ? ACTIVE_SECTION.prev("section") : (ctPosition > prevPosition) ? ACTIVE_SECTION.next("section") : ACTIVE_SECTION; // Determine scroll direction and target the next section
// If next section exists and is not current section: Scroll to it!
if(nextSection.length > 0 && nextSection !== ACTIVE_SECTION) {
$("body, html").animate({
'scrollTop': nextSection.offset().top
}, ANIMATION_DURATION).promise().then(function() {
// when animation is complete
prevPosition = $(window).scrollTop(); // remember remeasured .scrollTop()
ACTIVE_SECTION = nextSection; // remember active section
$(window).on("scroll", doScrollingStuff); // no need for additional delay after animation
});
} else {
setTimeout(function() {
$(window).on("scroll", doScrollingStuff);
}, 100); // Debounce
}
}
});

vertical slider on scroll

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!

Sticky navigation issue with touch devices

Have created a sticky menu, which is working fine for desktop and mobiles.
But there is a small issue with mobiles, when ever scrolling the page and the finger is still on the screen then
after reaching to the position of the container where the menu needs to stick it is not happening.
When I removed the finger from the screen, then it is taking a second time and the menu is getting fixed.
is there any solution for this, kindly help me with a sample demo.
Demo
JS:
var menuSection = $('.section') , navLists = $('.menu ul li'),
navLists_height = navLists.outerHeight(), headerOffset = $('.top_layer').offset().top;
$(window).on('scroll', function () {
var window_top = $(window).scrollTop() + 12;
if (window_top > headerOffset) {
$('.menu').addClass('fixed');
} else {
$('.menu').removeClass('fixed');
}
var cur_position = $(this).scrollTop()+70;
menuSection.each(function() {
var top = $(this).offset().top - navLists_height,
bottom = top + $(this).outerHeight();
if (cur_position >= top && cur_position <= bottom) {
navLists.find('a').removeClass('active');
menuSection.removeClass('active');
$(this).addClass('active');
navLists.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
}
});
});
navLists.find('a').on('click', function () {
var $el = $(this)
, id = $el.attr('href');
$('html, body').animate({
scrollTop: $(id).offset().top - navLists_height
}, 500);
return false;
});

Reposition DIV after scrolling

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

jQuery function losing the called elements and only keeping the last caller

I am developing a parallax site, and I want to ease out the elements when the scrolling has stopped. So I developed a plugin to detect when the scrolling stops, and once it stops, then smooth out the movement of the element (The object moves 5 pixels on to the direction in which the user was scrolling). It works but only to the last element that the plugin was applied to. When i was trying to debug, I see that both elements are still in effect inside the $(window).scroll(function(event) { but once we reach $(window).scrollStopped(function(){ only the last element is in effect. Any solutions?
// Scroll Direction set
var lastScrollTop = 0, scrollDirection = "";
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
scrollDirection = "down";
} else {
scrollDirection = "up";
}
lastScrollTop = st;
});
// Scroll Stopped detection
$.fn.scrollStopped = function(callback) {
$(this).scroll(function(){
var self = this, $this = $(self);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback,250,self));
});
};
// Smooth ending
$.fn.smoothStop = function () {
var $this = $(this);
$(window).scroll(function(event) {
$(window).scrollStopped(function(){
var top = parseFloat($this.css("top"));
if(scrollDirection == "down")
{
console.log(top, $this);
var new_top = top + 5;
$this.animate({
top: new_top + 'px'},
1000);
}
else{
var new_top = top - 5;
$this.animate({
top: new_top + 'px'},
1000);
}
});
});
};
$(".g6").smoothStop();
$(".g2").smoothStop();
JSFIDDLE
// Scroll Stopped detection
$.fn.scrollStopped = function(callback) {
$(this).scroll(function(){ <-- this is the window
var self = this, $this = $(self);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout')); <----timeout is removed from window
}
$this.data('scrollTimeout', setTimeout(callback,250,self)); <----timeout is set to window
});
};
basically you are trying to run multiple events, but you end up storing those multiple events in the same memory location. So when you add a new one, it cancells out the previous entry.

Categories

Resources