On my site I have it so my scroll is locked:
body {
overflow: hidden;
height: 100%;
}
and on click of buttons it scrolls to a certain div, all the divs are beneath each other, I would like to know if it is possible to check if the user 'tries' to scroll down or up, while scroll is locked, so if they try scroll down with the mouse wheel, I want to know how to do this so I can scroll down or up to the next div.
Any help is appreciated.
This will tell you if they are scrolling down or up. Then you would have to deal with the transition by yourself.
But in any case, if you are looking for a more tested solution, I would encourage you to use an already existent plugin such as fullPage.js which will provide old browser compatibility, touch detection, a proper solution for trackpads and Apple laptops/Magic Mouse, resize support and a lot of other useful features.
addMouseWheelHandler();
function MouseWheelHandler(e) {
// cross-browser wheel delta
e = window.event || e;
var value = e.wheelDelta || -e.deltaY || -e.detail;
var delta = Math.max(-1, Math.min(1, value));
//scrolling down?
if (delta < 0) {
console.log("scrolling down");
}
//scrolling up?
else {
console.log("scrolling up");
}
return false;
}
function addMouseWheelHandler() {
if (document.addEventListener) {
document.addEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper
document.addEventListener('wheel', MouseWheelHandler, false); //Firefox
} else {
document.attachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8
}
}
Related
I'm trying to catch whether the mousewheel is triggered and whether it's scrolled up or down without actually scrolling the page (body has an overflow: hidden).
Any idea's how I can achieve this using jQuery or pure javascript?
$(window).scroll(function(){
if( /* scroll up */){ }
else { /* scroll down */ }
});
I rarely promote plugins but this one is just excellent (and relatively small in size) :
https://plugins.jquery.com/mousewheel/
It'll allow to do something like this :
$(window).mousewheel(function(turn, delta) {
if (delta == 1) // going up
else // going down
// all kinds of code
return false;
});
http://codepen.io/anon/pen/YPmjym?editors=001
Update - at this point the mousewheel plugin could be replaced with the wheel event if legacy browsers need not be supported:
$(window).on('wheel', function(e) {
var delta = e.originalEvent.deltaY;
if (delta > 0) // going down
else // going up
return false;
});
This disables the scrolling.
NOTE: Notice it only stops scrolling if you hover over the element.
$('#container').hover(function() {
$(document).bind('mousewheel DOMMouseScroll',function(){
console.log('Scroll!');
stopWheel();
});
}, function() {
$(document).unbind('mousewheel DOMMouseScroll');
});
function stopWheel(e){
if(!e){ /* IE7, IE8, Chrome, Safari */
e = window.event;
}
if(e.preventDefault) { /* Chrome, Safari, Firefox */
e.preventDefault();
}
e.returnValue = false; /* IE7, IE8 */
}
Quoted from amosrivera's answer
EDIT: To check which way it is scrolling.
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
I am coding a page where the first time the user scrolls, it doesn't actually scroll the page down, instead it adds a class with a transition.
I'd like to detect when the user is scrolling down, because if he scrolls up, I want it to do something else.
All the methods that I've found are based on defining the current body ScrollTop, and then comparing with the body scrollTop after the page scrolls, defining the direction, but since the page doesn't actually scroll, the body scrollTop() doesn't change.
animationIsDone = false;
function preventScroll(e) {
e.preventDefault();
e.stopPropagation();
}
$('body').on('mousewheel', function(e) {
if (animationIsDone === false) {
$("#main-header").removeClass("yellow-overlay").addClass("yellow-overlay-darker");
$(".site-info").first().addClass("is-description-visible");
preventScroll(e);
setTimeout(function() {
animationIsDone = true;
}, 1000);
}
});
This is what I have come with, but that way it doesn't matter the direction I scroll it triggers the event
The mousewheel event is quickly becoming obsolete. You should use wheel event instead.
This would also easily allow you to the vertical and/or horizontal scroll direction without scroll bars.
This event has support in all current major browsers and should remain the standard far into the future.
Here is a demo:
window.addEventListener('wheel', function(event)
{
if (event.deltaY < 0)
{
console.log('scrolling up');
document.getElementById('status').textContent= 'scrolling up';
}
else if (event.deltaY > 0)
{
console.log('scrolling down');
document.getElementById('status').textContent= 'scrolling down';
}
});
<div id="status"></div>
Try This using addEventListener.
window.addEventListener('mousewheel', function(e){
wDelta = e.wheelDelta < 0 ? 'down' : 'up';
console.log(wDelta);
});
Demo
Update:
As mentioned in one of the answers, the mousewheel event is depreciated. You should use the wheel event instead.
I know this post is from 5 years ago but I didn't see any good Jquery answer (the .on('mousewheel') doesn't work for me...)
Simple answer with jquery, and use window instead of body to be sure you are taking scroll event :
$(window).on('wheel', function(e) {
var scroll = e.originalEvent.deltaY < 0 ? 'up' : 'down';
console.log(scroll);
});
Try using e.wheelDelta
var animationIsDone = false, scrollDirection = 0;
function preventScroll(e) {
e.preventDefault();
e.stopPropagation();
}
$('body').on('mousewheel', function(e) {
if (e.wheelDelta >= 0) {
console.log('Scroll up'); //your scroll data here
}
else {
console.log('Scroll down'); //your scroll data here
}
if (animationIsDone === false) {
$("#main-header").removeClass("yellow-overlay").addClass("yellow-overlay-darker");
$(".site-info").first().addClass("is-description-visible");
preventScroll(e);
setTimeout(function() {
animationIsDone = true;
}, 1000);
}
});
Note: remember that MouseWheel is deprecated and not supported in FireFox
this one work in react app
<p onWheel={this.onMouseWheel}></p>
after add event listener, in function u can use deltaY To capture mouse Wheel
onMouseWheel = (e) => {
e.deltaY > 0
? console.log("Down")
: console.log("up")
}
Tested on chrome and
$('body').on('mousewheel', function(e) {
if (e.originalEvent.deltaY >= 0) {
console.log('Scroll up'); //your scroll data here
}
else {
console.log('Scroll down'); //your scroll data here
}
});
I have a page with four main divs stacked vertically one by one . I need on scroll it should move between the divs directly not the normal scroll.
I am using ScrollTo plugin function for this but it is not working properly as i have to do all the operation on scroll but in the plugin example it is using buttons.
Anyone having any idea how i can do this?
I want a behaviour similar to this page.
Example
enter
http://jsfiddle.net/jLG7W/
The website you linked to as your example appears to be using the fullPage.js jQuery plugin. Which is what I'd guess you'd be after.
Edit:
To get this working without any plugins maybe try something like this
var divs = ["first","second","third","fourth"];
var counter = 0;
document.addEventListener("mousewheel", function(e) {
if(e.wheelDelta > 0){ // up
if(counter > 0){
counter--;
document.getElementById(divs[counter+1]).style.display = "none";
document.getElementById(divs[counter]).style.display = "block";
}
}
else if(e.wheelDelta < 0){ // down
if(counter < (divs.length-1)){
counter++;
document.getElementById(divs[counter-1]).style.display = "none";
document.getElementById(divs[counter]).style.display = "block";
}
}
});
Demo: http://jsfiddle.net/jLG7W/1/
If you want trigger scroll function when you actually scroll the mouse wheel, not only use keyboard arrows, then you should try reading this.
I made simple demo here in JSFiddle.
if (window.addEventListener) {
// IE9, Chrome, Safari, Opera
window.addEventListener("mousewheel", MouseWheelHandler, false);
// Firefox
window.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
}
// IE 6/7/8
else window.attachEvent("onmousewheel", MouseWheelHandler);
function MouseWheelHandler(e) {
// cross-browser wheel delta
var e = window.event || e; // old IE support
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
// Replace this IF statement with your code
if(delta==-1){
// Go to next slide
}else{
// Go to previous slide
}
return false;
}
I'm creating an ad for a magazine on iPad that has a long timeline that needs to be controlled by a horizontal scrollbar. The scrollbar had to be custom, and the best plugin for custom scrolling that I could find that worked on iPads was fleXcroll.
My problem is that I'm trying to disable the ability for the user to swipe scroll the timeline. It needs to be exclusively controlled by the scrollbar (since a swipe from the user should bring them to the next page of the magazine.)
I've been looking at this problem for the past two days and the closest I can get to solving it at the moment is by controlling the touch events for the div. When I use event.preventDefault() for touchstart and touchmove on the div it works partially. If the screen has not been moved, a swipe will not move the timeline. However, after using the scrollbar, if the timeline is still moving (iPads have a sort of easing when things are swiped so that whatever is being moved slows down before stopping) you can grab the timeline and move it by swiping it. Also, if you slowly let the scrollbar stop moving with your finger on it until it stops, you can then swipe the timeline again.
So, the problem is preventing the ability for users to swipe a certain div to the side in a magazine ad for iPad. The scrolling should ONLY be controlled by the scrollbar.
Any help is greatly appreciated! Thanks!
You can register JS to observe the swipe event and then just "ignore" them and prevent them from propagating further up the chain. Something like this might help:
(function($) {
$.fn.touchwipe = function(settings) {
var config = {
min_move_x: 20,
wipeLeft: function() { alert("left"); },
wipeRight: function() { alert("right"); },
preventDefaultEvents: true
};
if (settings) {
$.extend(config, settings);
}
this.each(function() {
var startX;
var isMoving = false;
function cancelTouch() {
this.removeEventListener('touchmove', onTouchMove);
startX = null;
isMoving = false;
}
function onTouchMove(e) {
if(config.preventDefaultEvents) {
e.preventDefault();
}
if(isMoving) {
var x = e.touches[0].pageX;
var dx = startX - x;
if(Math.abs(dx) >= config.min_move_x) {
cancelTouch();
if(dx > 0) {
config.wipeLeft();
}
else {
config.wipeRight();
}
}
}
}
function onTouchStart(e)
{
if (e.touches.length == 1) {
startX = e.touches[0].pageX;
isMoving = true;
this.addEventListener('touchmove', onTouchMove, false);
}
}
this.addEventListener('touchstart', onTouchStart, false);
});
return this;
};
})(jQuery);
Is there a way to get the mouse wheel events (not talking about scroll events) in jQuery?
$(document).ready(function(){
$('#foo').bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta /120 > 0) {
console.log('scrolling up !');
}
else{
console.log('scrolling down !');
}
});
});
Binding to both mousewheel and DOMMouseScroll ended up working really well for me:
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// scroll up
}
else {
// scroll down
}
});
This method is working in IE9+, Chrome 33, and Firefox 27.
Edit - Mar 2016
I decided to revisit this issue since it's been a while. The MDN page for the scroll event has a great way of retrieving the scroll position that makes use of requestAnimationFrame, which is highly preferable to my previous detection method. I modified their code to provide better compatibility in addition to scroll direction and position:
(function() {
var supportOffset = window.pageYOffset !== undefined,
lastKnownPos = 0,
ticking = false,
scrollDir,
currYPos;
function doSomething(scrollPos, scrollDir) {
// Your code goes here...
console.log('scroll pos: ' + scrollPos + ' | scroll dir: ' + scrollDir);
}
window.addEventListener('wheel', function(e) {
currYPos = supportOffset ? window.pageYOffset : document.body.scrollTop;
scrollDir = lastKnownPos > currYPos ? 'up' : 'down';
lastKnownPos = currYPos;
if (!ticking) {
window.requestAnimationFrame(function() {
doSomething(lastKnownPos, scrollDir);
ticking = false;
});
}
ticking = true;
});
})();
See the Pen Vanilla JS Scroll Tracking by Jesse Dupuy (#blindside85) on CodePen.
This code is currently working in Chrome v50, Firefox v44, Safari v9, and IE9+
References:
https://developer.mozilla.org/en-US/docs/Web/Events/scroll
https://developer.mozilla.org/en-US/docs/Web/Events/wheel
As of now in 2017, you can just write
$(window).on('wheel', function(event){
// deltaY obviously records vertical scroll, deltaX and deltaZ exist too.
// this condition makes sure it's vertical scrolling that happened
if(event.originalEvent.deltaY !== 0){
if(event.originalEvent.deltaY < 0){
// wheeled up
}
else {
// wheeled down
}
}
});
Works with current Firefox 51, Chrome 56, IE9+
There's a plugin that detects up/down mouse wheel and velocity over a region.
Answers talking about "mousewheel" event are refering to a deprecated event. The standard event is simply "wheel". See https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel
This worked for me:)
//Firefox
$('#elem').bind('DOMMouseScroll', function(e){
if(e.originalEvent.detail > 0) {
//scroll down
console.log('Down');
}else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
//IE, Opera, Safari
$('#elem').bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta < 0) {
//scroll down
console.log('Down');
}else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
from stackoverflow
Here is a vanilla solution. Can be used in jQuery if the event passed to the function is event.originalEvent which jQuery makes available as property of the jQuery event. Or if inside the callback function under we add before first line: event = event.originalEvent;.
This code normalizes the wheel speed/amount and is positive for what would be a forward scroll in a typical mouse, and negative in a backward mouse wheel movement.
Demo: http://jsfiddle.net/BXhzD/
var wheel = document.getElementById('wheel');
function report(ammout) {
wheel.innerHTML = 'wheel ammout: ' + ammout;
}
function callback(event) {
var normalized;
if (event.wheelDelta) {
normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
} else {
var rawAmmount = event.deltaY ? event.deltaY : event.detail;
normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
}
report(normalized);
}
var event = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
window.addEventListener(event, callback);
There is also a plugin for jQuery, which is more verbose in the code and some extra sugar: https://github.com/brandonaaron/jquery-mousewheel
This is working in each IE, Firefox and Chrome's latest versions.
$(document).ready(function(){
$('#whole').bind('DOMMouseScroll mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
alert("up");
}
else{
alert("down");
}
});
});
I was stuck in this issue today and found this code is working fine for me
$('#content').on('mousewheel', function(event) {
//console.log(event.deltaX, event.deltaY, event.deltaFactor);
if(event.deltaY > 0) {
console.log('scroll up');
} else {
console.log('scroll down');
}
});
use this code
knob.bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta < 0) {
moveKnob('down');
} else {
moveKnob('up');
}
return false;
});
The plugin that #DarinDimitrov posted, jquery-mousewheel, is broken with jQuery 3+. It would be more advisable to use jquery-wheel which works with jQuery 3+.
If you don't want to go the jQuery route, MDN highly cautions using the mousewheel event as it's nonstandard and unsupported in many places. It instead says that you should use the wheel event as you get much more specificity over exactly what the values you're getting mean. It's supported by most major browsers.
my combination looks like this. it fades out and fades in on each scroll down/up. otherwise you have to scroll up to the header, for fading the header in.
var header = $("#header");
$('#content-container').bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0) {
if (header.data('faded')) {
header.data('faded', 0).stop(true).fadeTo(800, 1);
}
}
else{
if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);
}
});
the above one is not optimized for touch/mobile, I think this one does it better for all mobile:
var iScrollPos = 0;
var header = $("#header");
$('#content-container').scroll(function () {
var iCurScrollPos = $(this).scrollTop();
if (iCurScrollPos > iScrollPos) {
if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);
} else {
//Scrolling Up
if (header.data('faded')) {
header.data('faded', 0).stop(true).fadeTo(800, 1);
}
}
iScrollPos = iCurScrollPos;
});
If using mentioned jquery mousewheel plugin, then what about to use the 2nd argument of event handler function - delta:
$('#my-element').on('mousewheel', function(event, delta) {
if(delta > 0) {
console.log('scroll up');
}
else {
console.log('scroll down');
}
});
I think many key things are a bit all over the place and I needed to read all the answers to make my code work as I wanted, so I will post my findings in just one place:
You should use "wheel" event over the other deprecated or browser specific events.
Many people here is getting something wrong: the opposite of x>0 is x<=0 and the opposite of x<0 is x>=0, many of the answers in here will trigger scrolling down or up incorrectly when x=0 (horizontal scrolling).
Someone was asking how to put sensitivity on it, for this you can use setTimeout() with like 50 ms of delay that changes some helper flag isWaiting=false and you protect yourself with if(isWaiting) then don't do anything. When it fires you manually change isWaiting=true and just below this line you start the setTimeout again who will later change isWaiting=false after 50 ms.
I got same problem recently where
$(window).mousewheel was returning undefined
What I did was $(window).on('mousewheel', function() {});
Further to process it I am using:
function (event) {
var direction = null,
key;
if (event.type === 'mousewheel') {
if (yourFunctionForGetMouseWheelDirection(event) > 0) {
direction = 'up';
} else {
direction = 'down';
}
}
}