public
Last active

Demo of hacks to prevent scroll-triggered navigation

  • Download Gist
README
1 2 3 4 5 6 7 8 9 10 11 12
The first approach use several layers. It takes advantage of the fact that you cannot trigger a "back" unless BODY's "scrollLeft" is 0. The disadvantage to this approach is the appearance of an additional horizontal scrollbar. There may also be some subtle side-effects to using "position: fixed".
 
1. The HTML element acts as a container for the BODY element, and uses "overflow: scroll".
2. The BODY element is 2 pixels wider than the page, so it can scroll 1px in either direction when its "scrollLeft" is 1 (neutral position).
3. We bind to the "onscroll" event of the window, and reset BODY's "scrollLeft" to 1.
4. The content is inside a DIV, which uses "position: fixed" so it doesn't jump around when the BODY is scrolling.
 
The second approach uses the hash / history stack. Rather than trying to stop a "back" or "forward", we simply "buffer" the history stack so that we can detect any changes and return to our neutral position.
 
1. When we load the page, we change the hash to "#previous", then "#neutral", then "#next".
2. We go back to "#neutral" using "window.history.back()".
2. We bind to the "onhashchange" event of the window, and reset the hash to "#neutral" as needed.
no_scroll_triggered_navigation.html
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
<!DOCTYPE html>
<html>
<head>
<title>No scroll-triggered page navigation</title>
<style>
html, body {
margin: 0;
padding: 0;
}
#content {
position: fixed;
left: 0;
top: 0;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('body')
.width( $(window).width() + 2 )
.height( $(window).height() )
.scrollLeft(1);
 
$('#scrollNavigationPreventionWrapper')
.width( $(window).width() - 20 )
.height( $(window).height() - 20 )
.css('padding', 10);
 
$(window).scroll(function(){
if ($('body').scrollLeft() !== 1) {
$('body').scrollLeft(1);
}
});
});
</script>
</head>
<body>
 
<div id="scrollNavigationPreventionWrapper">
 
<h1>No scroll-triggered page navigation</h1>
<p>Inspired by <a href="https://github.com/micho/jQuery.preventMacBackScroll">micho / jQuery.preventMacBackScroll</a>.</p>
 
<div style="margin-left:10%;width:80%;height:300px;overflow-x:scroll;overflow-y:hidden;position:relative;">
<div style="color:#fff;width:2000px;height:300px;position:absolute;background:-webkit-linear-gradient(-45deg, #3b679e 0%,#2b88d9 50%,#207cca 51%,#7db9e8 100%);">
<h1>Scroll Me!</h1>
</div>
</div>
 
</div>
 
</body>
</html>
no_scroll_triggered_navigation2.html
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
<!DOCTYPE html>
<html>
<head>
<title>No scroll-triggered page navigation</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
var originalLocation = window.location,
hashPos,
locationNoHash;
 
if ((hashPos = originalLocation.href.indexOf('#')) === -1) {
locationNoHash = originalLocation.href;
} else {
locationNoHash = originalLocation.href.substring(0, hashPos);
}
 
window.location = locationNoHash + '#back';
window.location = locationNoHash + '#neutral';
window.location = locationNoHash + '#forward';
window.history.back();
 
// setTimeout to allow code above to finish triggering "onhashchange" events.
window.setTimeout(function() {
var $span = $('p span');
$(window).on('hashchange', function(e) {
if (window.location.hash === '#forward') {
console.log('forward');
$span.text( $span.text() + 'forward ');
window.history.back();
} else if (window.location.hash === '#back') {
console.log('back');
$span.text( $span.text() + 'back ');
window.history.forward();
}
});
}, 100);
 
$('p a').click(function(e) {
// Clear
e.preventDefault();
$('p span').text('');
});
 
});
</script>
</head>
<body>
 
<h1>No scroll-triggered page navigation</h1>
<p><span></span> <a href="#">clear</a></p>
 
<div style="margin-left:10%;width:80%;height:300px;overflow-x:scroll;overflow-y:hidden;position:relative;">
<div style="color:#fff;width:2000px;height:300px;position:absolute;background:-webkit-linear-gradient(-45deg, #3b679e 0%,#2b88d9 50%,#207cca 51%,#7db9e8 100%);">
<h1>Scroll Me!</h1>
</div>
</div>
 
</body>
</html>

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.