How to prevent the user from interrupting window.scrollTo()? - javascript

I have a piece of code which uses window.scrollTo(), and I want to stop the user from interrupting the scrolling until it is finished.
let isMoving = false;
const scroll_keys = { 37: 1, 38: 1, 39: 1, 40: 1 };
preventDefault = e => {
console.log(isMoving);
if (!isMoving) return;
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
};
preventDefaultForScrollKeys = e => {
if (!isMoving) return;
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
};
document.addEventListener('wheel', preventDefault, { passive: false });
document.addEventListener('DOMMouseScroll', preventDefault, { passive: false });
document.addEventListener('scroll', preventDefault, { passive: false });
window.ontouchmove = preventDefault;
document.onkeydown = preventDefaultForScrollKeys;
function scrollTo(offset, callback) {
const onScroll = () => {
const scrollTop = window.scrollTop || window.pageYOffset;
if (scrollTop === offset) {
window.removeEventListener('scroll', onScroll);
callback();
}
};
window.addEventListener('scroll', onScroll);
onScroll();
window.scrollTo({
top: offset,
behavior: 'smooth',
});
}
I set isMoving = true before the call to window.scrollTo, and set it back to false in the callback, like this:
isMoving = true; scrollTo(0, () => { isMoving = false; });
I expect this to completely prevent the user from interrupting the scrolling but it doesn't work properly. It seems to work, but not every time, and it seems quite buggy.

Related

jQuery Full Page transition scroll

so I want to implement a full page transition scroll with jQuery. I know that there are plugins for this, but I need a custom code in my case.
//new script
<script>
$(document).ready(function(){
// http://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
function disableScroll() {
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll() {
if (window.removeEventListener)
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.ontouchmove = null;
document.onkeydown = null;
}
/* $(window).scroll(function(){
}); */
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
console.log('down');
if (($(this).scrollTop() >940) && ($(this).scrollTop() <1000)){
disableScroll();
$('html, body').animate({ scrollTop: $(".bg1").offset().top}, 2000);
enableScroll();
}
if ($(this).scrollTop() >1548){
disableScroll();
$('html, body').animate({ scrollTop: $(".bg2").offset().top}, 2000);
enableScroll();
}
} else {
// upscroll code
console.log('up');
/* if ($(this).scrollTop() >1548){
disableScroll();
$('html, body').animate({ scrollTop: $(".bg").offset().top}, 2000);
enableScroll();
} */
}
lastScrollTop = st;
});
}); //document.ready
</script>
So this is my script. It checks whether the scroll is up or down, then starting on the specified pixels it starts transitioning. The beginning is happening very well.The first transition is happening. However after that no matter if I scroll up or down it always transits back to the position of bg1. If I scroll very intensely sometimes the scrolling to the bg2 happens. What is the problem of my code?
Here is a working code with comments in it and the sources I used.
//$(document).ready(function(){ //disables all the scrolling
// $('body,html').css('overflow', 'hidden');
// });
// http://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
function disableScroll() {
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll() {
if (window.removeEventListener)
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.ontouchmove = null;
document.onkeydown = null;
}
//http://stackoverflow.com/questions/33838956/jquery-full-page-scroll-without-plugin
var currentLocation = 'firstPage';
// No need to set these inside the event listener since they are always the same.
var firstHeight = $('#firstPage').offset().top,
secondHeight = $('#secondPage').offset().top,
thirdHeight = $('#thirdPage').offset().top,
fourthHeight = $('#fourthPage').offset().top,
fifthHeight = $('#fifthPage').offset().top,
sixthHeight = $('#sixthPage').offset().top,
seventhHeight = $('#seventhPage').offset().top,
eightHeight = $('#eightPage').offset().top,
ninthHeight = $('#ninthPage').offset().top;
// Helper so we can check if the scroll is triggered by user or by animation.
var autoScrolling = false;
$(document).scroll(function(e){
var scrolled = $(window).scrollTop();
// Only check if the user scrolled
if (!autoScrolling) {
if (scrolled > 1 && currentLocation == 'firstPage') {
scrollPage(secondHeight, 'secondPage');
}
else if (scrolled > secondHeight + 1 && currentLocation == 'secondPage') {
scrollPage(thirdHeight, 'thirdPage');
}
else if (scrolled > thirdHeight + 1 && currentLocation == 'thirdPage') {
scrollPage(fourthHeight, 'fourthPage');
}
else if (scrolled > fourthHeight + 1 && currentLocation == 'fourthPage') {
scrollPage(fifthHeight, 'fifthPage');
}
else if (scrolled > fifthHeight + 1 && currentLocation == 'fifthPage') {
scrollPage(sixthHeight, 'sixthPage');
}
else if (scrolled > sixthHeight + 1 && currentLocation == 'sixthPage') {
scrollPage(seventhHeight, 'seventhPage');
}
else if (scrolled > seventhHeight + 1 && currentLocation == 'seventhPage') {
scrollPage(eightHeight, 'eightPage');
}
else if (scrolled > eightHeight + 1 && currentLocation == 'eightPage') {
scrollPage(ninthHeight, 'ninthPage');
}
else if (scrolled < ninthHeight - 1 && currentLocation == 'ninthPage') {
scrollPage(eightHeight, 'eightPage');
}
else if (scrolled < eightHeight - 1 && currentLocation == 'eightPage') {
scrollPage(seventhHeight, 'seventhPage');
}
else if (scrolled < seventhHeight - 1 && currentLocation == 'seventhPage') {
scrollPage(sixthHeight, 'sixthPage');
}
else if (scrolled < sixthHeight - 1 && currentLocation == 'sixthPage') {
scrollPage(fifthHeight, 'fifthPage');
}
else if (scrolled < fifthHeight - 1 && currentLocation == 'fifthPage') {
scrollPage(fourthHeight, 'fourthPage');
}
else if (scrolled < fourthHeight - 1 && currentLocation == 'fourthPage') {
scrollPage(thirdHeight, 'thirdPage');
}
else if (scrolled < thirdHeight - 1 && currentLocation == 'thirdPage') {
scrollPage(secondHeight, 'secondPage');
}
else if (scrolled < secondHeight - 1 && currentLocation == 'secondPage') {
scrollPage(firstHeight, 'firstPage');
}
}//autoScrolling IF
// Since they all have the same animation, you can avoid repetition
function scrollPage(nextHeight, page) {
currentLocation = page;
// At this point, the page will start scrolling by the animation
// So we switch this var so the listener does not trigger all the if/else
autoScrolling = true;
disableScroll();
$('body,html').animate({scrollTop:nextHeight}, 500, function () {
// Once the animation is over, we can reset the helper.
// Now it is back to detecting user scroll.
autoScrolling = false;
enableScroll();
});
}
//$('h1').html(scrolled);
//$('h1').append("/" + secondHeight);
//$('h1').append("/" + thirdHeight);
})//document.ready

javascript shortcut key / stop Interval function

i make a shortcut key for javascript function . i set the S key for start this and i so set the Z key for clear Interval function but im tired about this and when press Z key the Interval doesnt stop :(
var isCtrl = false;
document.onkeydown=function(e){
if(e.which == 83) {
var elem = document.elementFromPoint( cursorX,cursorY );
elem.addEventListener('click', function() {
console.log('clicked')
}, false);
var support = true;
try {
if (new MouseEvent('click', {bubbles: false}).bubbles !== false) {
support = false;
} else if (new MouseEvent('click', {bubbles: true}).bubbles !== true) {
support = false;
}
} catch (e) {
support = false;
}
var refreshIntervalId = setInterval(function() {
if (support) {
var event = new MouseEvent('click');
}else{
var event = document.createEvent('Event');
event.initEvent('click', true, true);
}
elem.dispatchEvent(event);
},10);
var cursorX;
var cursorY;
cursorX = 0; cursorY = 0;
document.onmousemove = function(e){
cursorX = e.clientX;
cursorY = e.clientY;
elem = document.elementFromPoint(e.clientX, e.clientY);
}
if(e.which == 90) {
clearInterval(refreshIntervalId);
}
}
}
help me i want to press Z key and Interval stop but i can`t ...
UPDATE : this code work correctly . use S key for start and Z key for stop the function .
var elem = document.elementFromPoint( cursorX,cursorY );
elem.addEventListener('click', function() {
console.log('clicked')
}, false);
var support = true;
try {
if (new MouseEvent('click', {bubbles: false}).bubbles !== false) {
support = false;
} else if (new MouseEvent('click', {bubbles: true}).bubbles !== true) {
support = false;
}
} catch (e) {
support = false;
}
var cursorX;
var cursorY;
cursorX = 0; cursorY = 0;
document.onmousemove = function(e){
cursorX = e.clientX;
cursorY = e.clientY;
elem = document.elementFromPoint(e.clientX, e.clientY);
}
var refreshIntervalId;
window.addEventListener("onkeydown", keyDown,true);
window.addEventListener("keydown", keyDown);
function keyDown() {
var e = window.event;
switch (e.keyCode) {
case 83:
start();
break;
case 90:
stop();
break;
}
}
function start() {
stop();
refreshIntervalId = setInterval(function() {
if (support) {
var event = new MouseEvent('click');
}else{
var event = document.createEvent('Event');
event.initEvent('click', true, true);
}
elem.dispatchEvent(event);
},1000);
}
function stop() {
if (refreshIntervalId != null) {
clearInterval(refreshIntervalId);
refreshIntervalId = null;
}
}
You also have to code it in a way to avoid starting the timer more than once. You should construct it more like this (move the var for the timer outside the function):
var refreshIntervalId;
window.addEventListener("onkeydown", keyDown,true);
window.addEventListener("keydown", keyDown);
function keyDown() {
var e = window.event;
switch (e.keyCode) {
case 83:
start();
break;
case 90:
stop();
break;
}
}
function start() {
stop();
refreshIntervalId = setInterval(function() {
// code...
},10);
}
function stop() {
if (refreshIntervalId != null) {
clearInterval(refreshIntervalId);
refreshIntervalId = null;
}
}
You doesn't seem to make an event to listen to keypress.
jQuery:
$(window).keypress(function(e) {
if (e.which == 90) {
clearInterval(refreshIntervalId);
}
});
Vanilla JS:
var keyEvent = function (e) {
if (e.which == 90) {
clearInterval(refreshIntervalId);
}
};
window.addEventListener('keypress', keyEvent);

Lock scollbar when mouse down and unlock when mouse up

iam trying to lock the scroll bar with the current position when mouse down event and also need to unlock when mouse up event
$('#table td').on('mousedown', function(){
$('#container').scrollLeft(0);
});
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
function disableScroll() {
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll() {
if (window.removeEventListener)
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.ontouchmove = null;
document.onkeydown = null;
}
$(document).ready( function(){
$('#table td').on('mousedown', function(){
disableScroll();
});
$('#table td').on('mouseup', function(){
enableScroll();
});
});
check this solution
based on this question
hope this helps

Prevent page scrolling while scrolling a div element

I have already found the solution in the accepted answer here:
How to prevent page scrolling when scrolling a DIV element?
But want also to disable scrolling the main page on keys (when div content can't be scrollable anymore).
I'm trying to make something like this but it's not working:
$( '.div-scroll' ).bind( 'keydown mousewheel DOMMouseScroll', function ( e ) {
var e0 = e.originalEvent,
delta = e0.wheelDelta || -e0.detail;
this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
e.preventDefault();
});
Any ideas why?
You can stop the scrolling of the whole page by doing:
Method 1
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
but it makes the browser's scrollbar disappear whenever you hover over the div.
Method 2
Else you can look at jquery-mousewheel.
var toolbox = $('#toolbox'),
height = toolbox.height(),
scrollHeight = toolbox.get(0).scrollHeight;
toolbox.off("mousewheel").on("mousewheel", function (event) {
var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
return !blockScrolling;
});
DEMO
Method 3
To stop the propagation with no plugins.
HTML
<div class="Scrollable">
<!-- A bunch of HTML here which will create scrolling -->
</div>
JS
$('.Scrollable').on('DOMMouseScroll mousewheel', function(ev) {
var $this = $(this),
scrollTop = this.scrollTop,
scrollHeight = this.scrollHeight,
height = $this.height(),
delta = (ev.type == 'DOMMouseScroll' ?
ev.originalEvent.detail * -40 :
ev.originalEvent.wheelDelta),
up = delta > 0;
var prevent = function() {
ev.stopPropagation();
ev.preventDefault();
ev.returnValue = false;
return false;
}
if (!up && -delta > scrollHeight - height - scrollTop) {
// Scrolling down, but this will take us past the bottom.
$this.scrollTop(scrollHeight);
return prevent();
} else if (up && delta > scrollTop) {
// Scrolling up, but this will take us past the top.
$this.scrollTop(0);
return prevent();
}
});
Method 4
you can do it by canceling these interaction events:
Mouse & Touch scroll and Buttons associated with scrolling.
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
function disableScroll() {
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll() {
if (window.removeEventListener)
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.ontouchmove = null;
document.onkeydown = null;
}
You need to bind document to 'keydown' event like this:
$( document ).bind( 'keydown', function (e) { ... e.preventDefault(); }
This code block the scrolling by using keys:
$(document).keydown(function(e) {
if (e.keyCode === 32 || e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40) {
return false;
}
});

Cross-browser method to disable vertical scrolling of window using JS/jQuery

I need to disable window scrolling when I mouseover a specific div and enable it on mouseout. But it's necessary to keep scrollbars, so overflow: hidden will not help.
I wrote a bit of JS, but it's to buggy in IE9 and Opera.
var win_scrolltop, is_mydiv_mouseovered = false;
$('#mydiv').hover(
function(){
win_scrolltop = $(window).scrollTop();
is_mydiv_mouseovered = true;
},
function() {
is_mydiv_mouseovered = false;
}
)
$(window).scroll(function() {
if (is_mydiv_mouseovered) $(window).scrollTop(win_scrolltop);
});
I found this answer, fiddled a little and result is this:
var scrollThing = {
// 33: PageUp, 34: PageDown, 35: End, 36: Home, 37: Left, 38: Up, 39: Right, 40: Down
keys: [33, 34, 35, 36, 37, 38, 39, 40],
preventDefault: function(e) {
e = e || window.event;
if (e.preventDefault) {
e.preventDefault();
}
e.returnValue = false;
},
keydown: function(e) {
for (var i = scrollThing.keys.length; i--;) {
if (e.keyCode === scrollThing.keys[i]) {
scrollThing.preventDefault(e);
return;
}
}
},
disable: function() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', scrollThing.preventDefault, false);
}
window.onmousewheel = document.onmousewheel = scrollThing.preventDefault;
document.onkeydown = scrollThing.keydown;
},
enable: function() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', scrollThing.preventDefault, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}
}
$('#mydiv').hover(scrollThing.disable, scrollThing.enable);
Working example.

Categories

Resources