Smooth scrolling for whole webpage - javascript

I am trying to add a smooth scroll to my website. Most of you think of a smooth scrolling animation when clicking on a button. But no! That's not what I want to achieve. When a user presses the key down, key upper or scrolls with the mouse wheel, I want to make a smooth animation to the point he scrolls to. I know it is possible. At this website, you can get a pure vanilla javascript code when you make a yearly subscription: http://www.smoothscroll.net/ . And I know that it works because I already saw it at other websites. My idea to achieve this by myself:
/*/////////////////////////////////////////////////////////////////////////////////////////////*/
/* S M O O T H S C R O L L */
/*/////////////////////////////////////////////////////////////////////////////////////////////*/
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e.preventDefault();
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
var supportsPassive = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
get: function () { supportsPassive = true; }
}));
} catch(e) {}
var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
// call this to Disable
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}
// call this to Enable
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}
disableScroll();
This is a stackoverflow answer. You can find the answer here: https://stackoverflow.com/a/4770179/12419967. The Problem now: I need to find out how much the user scrolled and than I could scroll it via script. But how? Or is there another solution or library we can use?

Related

Try remove window "wheel" event listener throw 'Unable to preventDefault inside passive event...'

I m trying to lock and unlock scroll interactions like this answer.
My Code
var preventDefault = function (e) {
e.preventDefault();
};
var preventDefaultSpecialKey = function (e) {
if (this.keys[e.keyCode]) {
preventDefault(e);
return false;
}
};
class Loader {
keys = { 37: 1, 38: 1, 39: 1, 40: 1 };
supportPassive = false;
get option() { return this.supportPassive ? { passive: false } : false; }
get event() { return "onwheel" in document.createElement("div") ? "wheel" : "mousewheel"; }
constructor() {
try {
const sP = () => (this.supportPassive = true);
window.addEventListener("test",null,
Object.defineProperty({}, "passive", { get: sP })
);
} catch (e) {}
}
open() {
window.addEventListener("DOMMouseScroll", preventDefault, false);
window.addEventListener(this.event, preventDefault, this.option);
window.addEventListener("touchmove", preventDefault, this.option);
window.addEventListener(
"keydown",
preventDefaultSpecialKey.bind(this),
false
); // Special keys
}
close() {
window.removeEventListener("DOMMouseScroll", preventDefault, false); // Throw warning on Firefox
window.removeEventListener(this.event, preventDefault, this.option); // Throw error on Chrome
window.removeEventListener("touchmove", preventDefault, this.option);
window.removeEventListener(
"keydown",
preventDefaultSpecialKey.bind(this),
false
);
}
}
Google Chrome -- Version 96.0.4664.93 (x64)
open method work as well, but after call close, window.removeEventListener(this.event, preventDefault, this.option); that throw an error: "Unable to preventDefault inside passive event listener due to target being treated as passive." when I trying scroll.
Firefox - Version 95.0 (x64)
open method work too, but after call close, window.removeEventListener("DOMMouseScroll", preventDefault, false); that throw the next warning (only one time):
"The "preventDefault()" call on a "DOMMouseScroll" event from a listener registered as "passive" was ignored." when I trying scroll.
I dont understand why error/warning is throwed, because I only remove event and not adding.
Any help will be much appreciate 💌.

lock scroll bar in certain section

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;
}
i found this code online , which will lock your scroll bar in all browser , i only want certain scroll bar to be lock , but this code lock all scroll bar.
i only want to lock the background scroll bar and i dont wanted to use css.
but as you see in demo both scroll wont move.
Demo
Javascript Solution
If you want really to use Javascript for this and to lock the scroll wheel (which is what you are doing) only when a user is on a specific div or element you can do that by adding an on hover listener to these elements:
$('#lock').hover(function() {
disableScroll();
}, function() {
enableScroll();
});
Check my jsFiddle for a working demo: http://jsfiddle.net/DHz77/553/
CSS Solution
If you want to disable the scrollbars and scrolling on a specific div using css rules, use:
#lock { /* or .classname */
height: 100%; /* or some px */
overflow-y:hidden;
}
In your case it was actually the body that was scrolling, so I had to adapt the css of the body as well:
Working demo: http://jsfiddle.net/DHz77/559/

Fancy Box 2 - Window jumping to top on click

This is my first time implementing FancyBox in a project for me. I have separated the image from the link. So when you hover over the image the link to view the large image appears. Everything there works fine. My issues is the window keeps jumping/scrolling to the top when the link is clicked. I have used jquery to disable the default action of it by using preventDefault but that didn't solve my issue. Any suggestions? You can see what I'm trying to accomplish at www.labpixls.com
I need to resolve this soon. I am creating a wordpress theme I plan on giving to the wp community.
The problem is that fancyBox changes the overflow value of the body in order to hide the browser scrollbars. This can actually be done with a helper in Fancybox 2.
$('.image').fancybox({
padding: 0,
helpers: {
overlay: {
locked: false
}
}
});
I realize this question has been asked a while ago, but I think I have found a good solution for it.
The problem is that fancy box changes the overflow value of the body in order to hide the browser scrollbars.
As Thorn points out, we can stop fancy box from doing this by adding the following parameters:
$('.image').fancybox({
padding: 0,
helpers: {
overlay: {
locked: false
}
}
});
But, now we can scroll the main page while looking at our fancy box window. It is better than jumping to the top of the page, but it is probably not what we really want.
We can prevent scrolling the right way by adding the next parameters:
$('.image').fancybox({
padding: 0,
helpers: {
overlay: {
locked: false
}
},
'beforeLoad': function(){
disable_scroll();
},
'afterClose': function(){
enable_scroll();
}
});
And add these functions from galambalaz. See: How to disable scrolling temporarily?
var keys = [37, 38, 39, 40];
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
}
function keydown(e) {
for (var i = keys.length; i--;) {
if (e.keyCode === keys[i]) {
preventDefault(e);
return;
}
}
}
function wheel(e) {
preventDefault(e);
}
function disable_scroll() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', wheel, false);
}
window.onmousewheel = document.onmousewheel = wheel;
document.onkeydown = keydown;
}
function enable_scroll() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', wheel, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}

disable webapp scrolling without killing click (tap) events in javascript

This is my first post so ill try to explain it clear:
Im working on a web application, but the main point is, that i want let my users feel like its a native app. In a native app you cant scroll like in iOS safari so i tried to disable scrolling with event.preventDefault. This works great except that form elements and links arent tapable anymore. My solution to that was this little script, but if you start a touch on one of the escaped elements, it scrolls anyway. Not a big deal but its driving me insane...
notes to script:
isTouch returns true/false if its a touchable device
the .contains method returns true/false if an array contains a string
if (isTouch) {
window.addEventListener("touchstart", function (evt) {
var target = evt.touches[0].target;
var tags = 'a input textarea button'.split(' ');
if ( tags.contains(target.tagName) === false ) {
evt.preventDefault();
}
}, false);
}
EDIT
My main question is, is there a solution to fire the tap event without a touchmove event to allow scrolling
EDIT 2
I solved the problem. My solution is, to emulate the events on interactive elements:
var eventFire = function (el, etype) {
if (el.fireEvent) {
(el.fireEvent('on' + etype));
}
else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
if (isTouch) {
window.addEventListener("touchstart", function (evt) {
var target = evt.touches[0].target;
var foc = 'input textarea'.split(' ');
var clck = 'a button'.split(' ');
if ( foc.contains(target.tagName) ) {
target.focus();
eventFire(target,'click');
evt.preventDefault();
}
else {
evt.preventDefault();
}
}, false);
}

how to prevent jumping site when scrolling?

I'm trying to write mechanism on site which prevents users to scroll normally. When user scrolls down or up the site is smoothscrolling to next or previous slide (depends on scrolling direction) and stops there (like when you click on a navbar). See live preview: CLICK HERE
But there's an annoying problem. It works almost good in FF (no jumping), but breaks in another browsers (Chrome, Safari, IE)- it jumps. How can I prevent this?Here are snippets from my code.
I have a ScrollControl object where I prevent scrolling:
scrollControl = {
keys : [32, 37, 38, 39, 40],
scrollTimer : 0,
lastScrollFireTime : 0,
preventDefault : function(e){
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
},
keydown : function(e){
for (var i = scrollControl.keys.length; i--;) {
if (e.keyCode === scrollControl.keys[i]) {
scrollControl.preventDefault(e);
return;
}
}
},
wheel : function(e){
scrollControl.preventDefault(e);
},
disableScroll : function(){
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', scrollControl.wheel, false);
}
window.onmousewheel = document.onmousewheel = scrollControl.wheel;
document.onkeydown = scrollControl.keydown;
},
enableScroll : function(){
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', scrollControl.wheel, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}
}
Then I'm listening if mousewheel occurs and trying to execute function only once (I'm using this plugin to detect mousewheel PLUGIN )
$(window).mousewheel(function(objEvent, intDelta){
var minScrollTime = 1000;
var now = new Date().getTime();
function processScroll() {
console.log("scrolling");
if(intDelta>0){
$.smoothScroll({
speed:med.effectDuration,
easing:med.scrollEase,
scrollTarget:med.prevPage,
afterScroll: function(){
med.currentPage = med.prevPage;
med.setActiveNav();
med.setSlides();
med.runAnimations();
}});
}else if(intDelta<0){
//scrollControl.disableScroll();
$.smoothScroll({
speed:med.effectDuration,
easing:med.scrollEase,
scrollTarget:med.nextPage,
afterScroll: function(){
med.currentPage = med.nextPage;
med.setActiveNav();
med.setSlides();
med.runAnimations();
}});
}
}
if (!scrollControl.scrollTimer) {
if (now - scrollControl.lastScrollFireTime > (3 * minScrollTime)) {
processScroll(); // fire immediately on first scroll
scrollControl.lastScrollFireTime = now;
}
scrollTimer = setTimeout(function() {
scrollControl.scrollTimer = null;
scrollControl.lastScrollFireTime = new Date().getTime();
processScroll();
}, minScrollTime);
}
});
I'm executing scrollControl.disableScroll function on DOM ready event when users starts website. And actually scrolling once prevention doesn't works prefectly and sometimes it triggers smoothscrolling twice. What am I doing wrong? Thanks in advance for any suggestions!
I had the same issue the Mouse Wheel Event was fired Twice.
function wheelDisabled(event){
event.preventDefault();
event.stopImmediatePropagation();
return false;
}
Also you might use both of these Events.
window.addEventListener('DOMMouseScroll', wheel, false);
window.addEventListener('mousewheel', wheel, false);
Instead of trying to prevent scrolling with Javascript, I would try a different approach. This approach includes CSS and Javascript to make sure the website is never bigger then the viewport (hence no scrollbars!).
Use CSS to force the main wrapping div (a div that wraps all the content on the site) to have overflow: hidden. Then use Javascript to dynamically ensure that the height and width of this div is always equal to the viewport's height and width.
In this scenario, if you want to implement scrolling in a predefined way you choose you can dynamically add negative margin-top (or negative margin-left for horizontal scrolling) to the parent wrapping div to give it the appearance that it is scrolling.

Categories