Disable all scrolling on webpage - javascript

I would like to know if it is possible to disable all scrolling on a webpage.
I am currently using
html, body { overflow:hidden; }
The issue is that this does not work on iOS devices and if you hold in the mouse wheel and drag it down you can also scroll, so it seems like a very poor solution to the problem
Is there a way to disable all methods of scrolling on all devices and then re-enable it?

I have had this exact same issue, i fixed it with the following;
var disableScroll = false;
var scrollPos = 0;
function stopScroll() {
disableScroll = true;
scrollPos = $(window).scrollTop();
}
function enableScroll() {
disableScroll = false;
}
$(function(){
$(window).bind('scroll', function(){
if(disableScroll) $(window).scrollTop(scrollPos);
});
$(window).bind('touchmove', function(){
$(window).trigger('scroll');
});
});
the touch move is bound to the window as the window scroll event is not fired until touch move is completed, so this allows a much smoother experience on iOS!
This isn't a perfect solution as you can 'throw' the page, but it will return to desired position when the throw has complete (as the window scroll event will then be fired). This is because iOS browsers strip out a lot of events for performance. also setTimeout and setInterval functions do not fire whilst the page is being thrown, having a loop isn't an option either!
see here http://jsfiddle.net/8T26k/

Related

detect (event) attempting to scroll up/down when already at top/bottom of the page with javascript or angularJS,

so i want to detect scrolling to the top(or bottom) when i'm already at the top(or bottom) of the page. I've seen a couple questions with similar problems here, but the only answer was to detect mousewheel event.
but considering the fact that i want to detect it when it's triggered by any similar action (like pressing the up/down key, or mousewheel and touchpad scrolling, or pageUp/Down, or home/end ...) should I create eventlisteners for each and every one of them? does anyone know a better way of doing it??
This is what I have for you so far. I can detect when you hit the top or bottom regardless of how you scrolled. The issue is detecting when you are trying to keep scrolling after you reached it because the scroll event does not fire unless you actually scroll. The only thing I can think of is to programmatically scroll the screen up slightly so that you can scroll again, but I don't recommend doing that. Other than this I don't see any other way other than creating custom events for each possible way the user can scroll.
$(function(){
var lastScrollBarPos = 0;
$(window).scroll(function(event){
var browserViewportHeight = $(window).height();
var hmtlDocHeight = $(document).height();
var scrollBarPos = $(window).scrollTop();
if (scrollBarPos > lastScrollBarPos){
// downscroll code
console.log('scroll down');
if(hmtlDocHeight == browserViewportHeight + scrollBarPos){
console.log('reached bottom');
}
} else {
// upscroll code
console.log('scroll up');
if(scrollBarPos == 0){
//we are at the top and someone is scrolling
console.log('reached top');
}
}
lastScrollBarPos = scrollBarPos;
});
});

How to Synchronize Scroll Between two windows

I have a popup window in my site that show additional information about the elements been show in the main screen. I need to syncronize the scrolling between the two windows, in a way that when the user scroll one of the window , the other window is automatticaly scrolled in the same ammount.
I was able to do that using jquery scroll event, and using the scrollTop function to set the scroll position. something like this:
$("#localDiv").scroll(function() {
var scrollPos = $("#localDiv").scrollTop();
$("targetElement").scrollTop( scrollPos );
});
I've simplified the actual code, because I have to do some work to reach the elements in another window, but this is not the question.
The problem is, this code works fine in Chrome and IE, but in FireFox the scrolling gets really slow.
I've created an example here : http://jsfiddle.net/Lv2dw787/4/. The problem seems to ocurr with DIV's in the same page as well. You can note that when the scrolling syncing is disabled, the speed turn back to normal.
Does anyone have a clue on how to fix this on FireFox?
Edit after Dave Chen answer:
The accepted answer solved my problem, but it has a catch. I first tried to do this:
lock = true;
try {
var scrollPos = $("#contentDivA").scrollTop();
$("#contentDivB").scrollTop( scrollPos );
}
finally
{
lock = false;
}
But the $("#contentDivB").scrollTop( scrollPos ); line seems to generate a scroll event on divB only after the current function finishes executing, so the finally part of try..finally was executing before that. So I had to this:
lock = true;
var scrollPos = $("#contentDivA").scrollTop();
$("#contentDivB").scrollTop( scrollPos );
and on DivB scroll event:
if (lock)
lock = false;
else {
(Do the scroll on DivA)
}
The reason is because of two reasons:
Firefox does smoothing on its scrolling
jQuery's scrollTop will trigger events
Let's look at some pseudo-code:
When divA is scrolled -> scroll divB to the same spot
When divB is scrolled -> scroll divA to the same spot
The problem is that when you scroll divA or divB to the same spot, it will also cause the when to happen again.
So for example, when you scroll divA, this is what happens:
scroll divA -> scroll divB to the same spot -> scroll divA to the same spot
This causes divA to stick to the same spot after scrolling a little, and thus what causes the sluggish effect in firefox.
A solution is to ignore scrolling events when you scroll:
$(document).ready(function() {
var ignore = false;
$("#contentDivA").scroll(function() {
var tmpIgnore = ignore;
ignore = false;
if (!tmpIgnore && $("#chkSyncEnabled")[0].checked)
{
var scrollPos = $("#contentDivA").scrollTop();
scrollTop($("#contentDivB"), scrollPos);
}
});
$("#contentDivB").scroll(function() {
var tmpIgnore = ignore;
ignore = false;
if (!tmpIgnore && $("#chkSyncEnabled")[0].checked)
{
console.log("here");
var scrollPos = $("#contentDivB").scrollTop();
scrollTop($("#contentDivA"), scrollPos);
}
});
function scrollTop(el, position) {
ignore = true;
el.scrollTop(position);
}
});
Example

trigger event on reaching browser bottom

$(window).scroll(function(){
if(window.reachBrowserBottom) {
alert('browser bottom reached');
}
}
I want to trigger an event when browser scrolling reaches the bottom. To load more content, much like sites like Facebook or Quora do it.
I tried:-
var bottomReached = $(window).height() = $(window).scrollTop();
if(bottomReached) {
...
}
But bottomReached is a bit unpredictable.
Check out this answer. It addresses the same issue.
https://stackoverflow.com/a/3898152/1341823
You need to use the .scroll() event on window.

How to check each new scroll and avoid Apple mouses issue (multiple-scroll effect)

I try to make a mousewheel event script, but getting some issues since I'm using an Apple Magic Mouse and its continue-on-scroll function.
I want to do this http://jsfiddle.net/Sg8JQ/ (from jQuery Tools Scrollable with Mousewheel - scroll ONE position and stop, using http://brandonaaron.net/code/mousewheel/demos), but I want a short animation (like 250ms) when scrolling to boxes, AND ability to go throught multiple boxes when scrolling multiple times during one animation. (If I scroll, animation start scrolling to second box, but if I scroll again, I want to go to the third one, and if I scroll two times, to the forth, etc.)
I first thought stopPropagation / preventDefault / return false; could "stop" the mousewheel velocity (and the var delta) – so I can count the number of new scroll events (maybe with a timer) –, but none of them does.
Ideas?
EDIT : If you try to scroll in Google Calendars with these mouses, several calendars are switched, not only one. It seems they can't fix that neither.
EDIT 2 : I thought unbind mousewheel and bind it again after could stop the mousewheel listener (and don't listen to the end of inertia). It did not.
EDIT 3 : tried to work out with Dates (thanks to this post), not optimal but better than nothing http://jsfiddle.net/eZ6KE/
Best way is to use a timeout and check inside the listener if the timeout is still active:
var timeout = null;
var speed = 100; //ms
var canScroll = true;
$(element).on('DOMMouseScroll mousewheel wheel', function(event) {
// Timeout active? do nothing
if (timeout !== null) {
event.preventDefault();
return false;
}
// Get scroll delta, check for the different kind of event indexes regarding delta/scrolls
var delta = event.originalEvent.detail ? event.originalEvent.detail * (-120) : (
event.originalEvent.wheelDelta ? event.originalEvent.wheelDelta : (
event.originalEvent.deltaY ? (event.originalEvent.deltaY * 1) * (-120) : 0
));
// Get direction
var scrollDown = delta < 0;
// This is where you do something with scrolling and reset the timeout
// If the container can be scrolling, be sure to prevent the default mouse action
// otherwise the parent container can scroll too
if (canScroll) {
timeout = setTimeout(function(){timeout = null;}, speed);
event.preventDefault();
return false;
}
// Container couldn't scroll, so let the parent scroll
return true;
});
You can apply this to any scrollable element and in my case, I used the jQuery tools scrollable library but ended up heavily customizing it to improve browser support as well as adding in custom functionality specific to my use case.
One thing you want to be careful of is ensuring that the timeout is sufficiently long enough to prevent multiple events from triggering seamlessly. My solution is effective only if you want to control the scrolling speed of elements and how many should be scrolled at once. If you add console.log(event) to the top of the listener function and scroll using a continuous scrolling peripheral, you will see many mousewheel events being triggered.
Annoyingly the Firefox scroll DOMMouseScroll does not trigger on magic mouse or continuous scroll devices, but for normal scroll devices that have a scroll and stop through the clicking cycle of the mouse wheel.
I had a similar problem on my website and after many failed attempts, I wrote a function, which calculated total offset of selected box and started the animation over. It looked like this:
function getOffset() {
var offset = 0;
$("#bio-content").children(".active").prevAll().each(function (i) {
offset += $(this)[0].scrollHeight;
});
offset += $("#bio-content").children(".active")[0].scrollHeight;
return offset;
}
var offset = getOffset();
$('#bio-content').stop().animate( {
scrollTop: offset
}, animationTime);
I hope it gives you an idea of how to achieve what you want.
you can try detecting when wheel stops moving, but it would add a delay to your response time
$(document).mousewheel(function() {
clearTimeout($.data(this, 'timer'));
$.data(this, 'timer', setTimeout(function() {
alert("Haven't scrolled in 250ms!");
//do something
}, 250));
});
source:
jquery mousewheel: detecting when the wheel stops?
or implement flags avoiding the start of a new animation
var isAnimating=false;
$(document).bind("mousewheel DOMMouseScroll MozMousePixelScroll", function(event, delta) {
event.preventDefault();
if (isAnimating) return;
navigateTo(destination);
});
function navigateTo(destination){
isAnimating = true;
$('html,body').stop().animate({scrollTop: destination},{complete:function(){isAnimating=false;}});
}

prevent window from dragging in ios5 mobile browser

I'm working on an iPad browser games and can't seem to lock the window. I've prevented scroll bars using typical overflow techniques, but the entire window still drags up and down (the new rubberband - type effect)
Is there a way to remove this window dragging?
Thannks
Bind to touchmove and preventDefault action which is scrolling
document.body.addEventListener('touchmove', function (ev) {
ev.preventDefault();
});
Or with jQuery
$('body').bind('touchmove', function (ev) {
ev.preventDefault();
});
EDIT: I've actually come across another solution that may be even easier, try this
body { overflow: hidden; }

Categories

Resources