I'm developing a function which scrolls to every image, but when in text i'd like to emulate the spacebar function
So the code I have is:
window.scrollBy(0,window.innerHeight*0.8);
but I'd like to be more accurate so does anyone knows the native code of the space bar scroll function?
window.scrollTo will do that. You'll have to use the current scroll position + a set interval like
window.scrollTo(0, window.scrollY+=200)
I'm not sure what interval the space bar actually uses but I'm sure you can find a value you're happy with.
edit: window.pageYOffset might be more browser friendly. Here's the space bar emulated in your own code. Not sure why you'd want to:
document.onkeydown = function(event) {
if(event.keyCode===32){
event.preventDefault();
window.scrollTo(0, window.pageYOffset+=window.innerHeight*0.8)
}
}
Related
I have a site where I have each section as 100vh so it fills the height of the screen perfectly. The next step I wanted to implement was disabling the regular scrolling, and on scroll force the screen to jump smoothly to the top of the next 100vh section. Here is the example of this animation / feature:
https://www.quay.com.au/
I was having a hard time finding any answers for this as most things just deal with smooth scrolling when clicking on anchors, not actually forcing div relocation when the user scrolls up / down.
I just wanted to know what code I would need do this...
Thanks, been using stack overflow for a while but first post, let me know if there is anything I can do to make this more clear.
disclaimer: this solution needs some testing and probably a bit of improvements, but works for me
if you don't want to use a plugin and prefer a vanilla JavaScript solution I hacked together a small example how this can be achieved with JS features in the following codepen:
https://codepen.io/lehnerchristian/pen/QYPBbX
but the main part is:
function(e) {
console.log(e);
const delta = e.deltaY;
// check which direction we should scroll
if (delta > 0 && currentlyVisible.nextElementSibling) {
// scroll downwards
currentlyVisible = currentlyVisible.nextElementSibling;
} else if (delta < 0 && currentlyVisible.previousElementSibling) {
// scroll upwards
currentlyVisible = currentlyVisible.previousElementSibling;
} else {
return false;
}
// perform scroll
currentlyVisible.scrollIntoView({ behavior: 'smooth' });
e.preventDefault();
e.stopPropagation();
}
what it does is that it listens for the wheel event and then calls the callback, which intercepts the scroll event. inside the callback the direction is determined and then Element.scrollIntoView() is called to let the browser do the actual scrolling
check https://caniuse.com/#search=scrollintoview for browser support, if you're going for this solution
On refreshing a long HTML page, the scroll position is initialized to the top and then jumped to the last scroll position.
Is there a way to stop this scroll jump behavior on refresh and just initialize scroll position to last scroll position?
How about use html5 localStorage function.
window.addEventListener('scroll', function () {
localStorage.scrollX = window.scrollX;
localStorage.scrollY = window.scrollY;
})
window.addEventListener('load',function () {
window.scrollTo(localStorage.scrollX || 0, localStorage.scrollY || 0);
})
Check it on http://jsfiddle.net/g5NKG/10/show/
It sounds like you may need the .scrollTop() method from jQuery found here
So:
$(document).ready(function(){
$(this).scrollTop(0);
});
From link in comments, this also is a quick fix:
$(document).scrollTop(0);
Isn't this just default browser behavior? What you're describing sounds like all mayor browsers are already doing it like that.
I'm running into a problem that's actually a "feature" on Chrome.
As most of you might know, Chrome remembers a scroll position that it returns to, whenever you come back to a page. And I kind of have a problem with that.
Is there any way to override this without the user noticing?
Mees
Failed try-outs:
ScrollTop on document.ready
In Chrome 46+, the auto scroll behavior can be turned off using history.scrollRestoration:
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
source: https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration
I've checked on chrome, it worked well. Sometimes setTimeout does trick :)
<script type="text/javascript">
window.onload=function(){
setTimeout(function(){
scrollTo(0,-1);
},0);
}
</script>
x = 0; //horizontal coord
y = document.height; //vertical coord
window.scroll(x,y);
Some Javascript like that may very well be able to be manipulated to stop the auto scrolling.
It depends though, are you happy for the scroll to be simply set to automatically go to the top, or are you actually looking for the Chrome standard option to take the page to last scroll position, to be turned off completely?
What are you currently attempting to use for scrollTop()?
I solved this by attaching to scroll event, and then resetting scroll position the first time a user scrolls. Works for on-spot reloads for me.
Looks like this:
var scrollResetOnce = false;
$(window).on("scroll", function() {
if (scrollResetOnce) return;
scrollResetOnce = true;
scrollTo(0, -1);
});
Here is a clean way of getting this done.
window.addEventListener('unload', function(e){
document.body.style.display = 'none';
});
By simply setting the body display to 'none' you don't have to worry about a flash of the browser scrolling to the top of the page before it is unloaded and the scroll position will automatically be reset to 0.
I am using the most wonderful javascript tool iScroll4 http://cubiq.org/iscroll-4 on a mobile website for iOS and Android. Here is what my layout looks like:
The horizontally scroll-able area is making use of iScroll4 with the following settings:
var myScroll = new iScroll('frame', { hScrollbar: false, vScrollbar: false, vScroll: false })
The horizontal scrolling part works great. This issue is what happens when a user attempts to scroll up or down the page placing their finger on the horizontal scrolling area. So I need native vertical scrolling, and iScroll horizontal scrolling on the same area.
What I have tried so far:
Removing e.preventDefault() in the iScroll code (allows for native scrolling, but in BOTH axes).
Removing e.preventDefault() and then disabling horizontal scrolling page wide with this:
var touchMove;
document.ontouchstart = function(e){
touchMove = e.touches[0];
}
document.ontouchmove = function(e){
var theTouch = e.touches[0] || e.changedTouches[0];
var Xer = rs(touchMove.pageX - theTouch.pageX).toPos();
var Yer = rs(touchMove.pageY - theTouch.pageY).toPos();
touchMove = theTouch;
if(Yer > Xer){ e.preventDefault(); }
}
which seems to do nothing. How can I allow for native vertical scrolling in the horizontal scrolling area, without loosing the horizontal scrolling of iScroll? I am really stumped here. Thanks in advance.
(just for the record rs(foo).toPos() is a function that makes foo a positive number regardless of its value).
If you would like to achieve the effect described by Fresheyeball without hacking the core, and without changing from iScroll to swipeview, then iScroll 4 does offer you its event listeners to work with.
myScroll = new iScroll('scrollpanel', {
// other options go here...
vScroll: false,
onBeforeScrollMove: function ( e ) {
if ( this.absDistX > (this.absDistY + 5 ) ) {
// user is scrolling the x axis, so prevent the browsers' native scrolling
e.preventDefault();
} else {
// delegate the scrolling to window object
window.scrollBy( 0, -this.distY );
}
},
});
By doing so, the onBeforeScrollMove-Handler checks whether the scroll direction seems to be horizontal, and then prevents the default handler, thus effectively locking the scroll action to the X-Axis (try commenting it out, you'll see the difference). Otherwise, if the scroll direction needs to be vertical, we make the browser scroll via the window.scrollBy() method. This is not exactly native, but does the job just fine.
Hope that helps
Lukx
[EDIT]
My original solution, which didn't use window.scrollBy() ,did not work on slower Samsung phones, which is why I needed to adapt the answer.
Suggested edit to #Lukx's excellent solution. New versions of iScroll4 place the e.preventDefault() in onBeforeScrollMove which can be overridden. By placing the if block into this option, default is not prevented for vertical scrolling, and vertical can scroll natively.
myScroll = new iScroll('scrollpanel', {
// other options go here...
vScroll: false,
onBeforeScrollStart: function ( e ) {
if ( this.absDistX > (this.absDistY + 5 ) ) {
// user is scrolling the x axis, so prevent the browsers' native scrolling
e.preventDefault();
}
},
});
With iscroll 5, you can set eventPassthrough: true to achieve this. See http://iscrolljs.com/#configuring
OLD ANSWER
UPDATE a special pluggin has been written just to address this problem:
http://cubiq.org/swipeview
I found a way!
add a variable to the top of the document: if android is 15 and is iOS is 3
var scrollTolerance = ( rs().isDevice('android') )?15:3;
disable the original e.preventDefault(); for scrolling. This is under onBeforeScrollStart:
the in _move just under
timestamp = e.timeStamp || Date.now();
add this line
if( Math.sqrt(deltaX*deltaX) > scrollTolerance){e.preventDefault();}
What this does is the following:
the scrollTolerance sets, you guessed it, a tolerance for finger direction. We don't want to demand a perfect vertical angle to get the up down native scroll. Also iOS does not detect properly and will never be higher than 4 for some reason so I used 3. Then we disable iScroll's standard e.preventDefault(); which prevents native vertical scrolling on our bi-scrollable area. Then we insert e.preventDefault(); only upon move and based on finger direction from tolerance.
This does not work perfect. But is acceptable and works on iOS and Android. If anyone sees better ways please post here. This is something I (and assume others) need to use regularly, and we should have a perfect rock solid solution.
Thanks.
Please test this solution from Adam.
https://gist.github.com/hotmeteor/2231984
I think the trick is to add the check in onBeforeScrollMove. First get the initial touch position in onBeforeScrollTouchStart and then in onBeforeScrollMove check the new position and then disable the required scroll based on the difference.
iScroll 5 supports native scrolling of any axis!
http://iscrolljs.com/
on iScroll5 just set eventPassthrougt to true. That fixes it.
You can view the site at www.highdwellercreative.com/colife. This site is based around the concept the the city will grow as the company grows and we wanted a different feeling then scrolling with the scroll bars provided. I have been working on a keypad style of navigation that consists of four directional arrows (up, down, left, right).
I am currently using setInterval() function to loop the scrollTo Plugin on mousedown() and the clearInterval() function to end the loop on mouseup().
I have also set the interval to repeat at 1 millisecond to achieve smooth scrolling. I have included the code that makes what I have accomplished so far work but it is still a bit rough, especially in Firefox 4. So far this does work in all browsers, including IE, but it could stand to be smoother and I am at a loss of how to accomplish this. Also if you click on one of the navigation buttons and immediately do a right click on it, the page gets stuck scrolling in that direction. Any help on how to improve this would be greatly appreciated.
var rightId;
$('span#right').mousedown(function() {
rightId = setInterval(function(){$.scrollTo('+=5px', {axis:'x'})}, 1);
}).mouseup(function() {
clearInterval(rightId);
});
var leftId;
$('span#left').mousedown(function() {
leftId = setInterval(function(){$.scrollTo('-=5px', {axis:'x'})}, 1);
}).mouseup(function() {
clearInterval(leftId);
});
var upId;
$('span#up').mousedown(function() {
upId = setInterval(function(){$.scrollTo('-=5px', {axis:'y'})}, 1);
}).mouseup(function() {
clearInterval(upId);
});
var downId;
$('span#down').mousedown(function() {
downId = setInterval(function(){$.scrollTo('+=5px', {axis:'y'})}, 1);
}).mouseup(function() {
clearInterval(downId);
});
You could certainly put these all into a single function:
function moveAround(elem,dir,moveAxis) {
var moving;
$(elem).mousedown(function() {
moving = setInterval(function(){$.scrollTo(dir+'=5px', {axis:moveAxis})}, 1);
}).mouseup(function() {
clearInterval(moving);
});
}
moveAround('span#left','-','x');
moveAround('span#right','+','x');
moveAround('span#up','-','y');
moveAround('span#down','+','y');
Just in terms of functionality, you may want to make a double click move you 500px or something. Just so people can get around the city faster. :)
An alternative way to do this would be to use .animate, with a callback function that called the same function (as long as the mousedown was still active).