Horizontal scrolling act for vertical built page - javascript

I have built my own web page based on the same concept as this demo: https://ihatetomatoes.net/demos/full-screen-layout-with-skrollr/
The problem is when inexperienced users browse on their mobile units. They immediately try to scroll horizontally mid way through the page.
My intention is to enable horizontal scrolling as it were vertical as well. That would be to interpret "scrolling" right on an iPad would be equal to vertical scrolling downward. In addition to normal vertical scrolling.
Is there any jquery function to enable this ?

I doubt your usability design is the best, because the behaviour of 'inexperienced' users might just be the way normal users are used to interact with an app/webpage. Fancy animations might look cool, but could distract from the content and confuse people.
In case you want to try it anyway, here is what i came up with:
$(window).scroll(function() {
var currPos = $(document).scrollLeft();
var callback = function() {
animationComplete = true;
}
if (lastPos < currPos && animationComplete) {
animationComplete = false;
console.log('scroll right');
$('body, html').animate({scrollTop: 200}, callback);
}
});
If a scrolling event happens, it checks if it was horizontal. If that is the case, a downward animation is triggered. Callback function is there so that no further animations are triggered, while still animating (otherwise it would block the vertical scrolling).
http://codepen.io/TobiObeck/pen/jrKBQw

Related

How to create forced scrolling to anchors on a website on scroll

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

iOS Safari Overscrolling: Pulling down vs. bouncing

My team and me are developing a web application which bears a fixed header, that doesn't scroll.
In order to handle overscrolling on iOS, we need to detect scrolling in negative direction and reposition the fixed header as static again to make it scroll along with the rest of the page.We do this by binding a jQuery scroll handler to window:
$(window).scroll(function() {
if ($(window).scrollTop() < 0) {
// position static header postioning in order
// let the header behave correctly when overscrolling
}
});
This works well, when the page is manually pulled (dragged) down.
But as every iOS user knows, when scrolling the page from a downwards position with speed up again, it bounces (overscrolls), once it reaches its top.
In this case, our scroll handling doesn't work.
At the moment I can imagine two reasons, why this different behaviour occurs:
Rapid scrolling upwards, and making a page bounce, is too fast for Safari's JS engine to ensure a fluid handling
Is bouncing when scrolling upwards technically the same as manually pulling down a webpage? In respect to $(window).scrollTop() ?
Has anybody some hints how to make my scroll handling work in both cases?
If position:fixed in CSS isn't working for you, then you should try to make a draw loop, and every single time that loop runs, you place a horizontal offset that is equal to how far your user has scrolled.
Basically, your JS should look like this if CSS doesn't work:
var head = document.getElementById("header");
//head now has our header
head.style.position = "relative";
//and now, we can manipulate it's position
function draw(){
head.style.top = window.pageYOffset;
//all that's left to do is do this each and every frame.
}
And if you don't know how to make a draw loop, here's the code:
var frameRate = 60;
var frameCounter = (function(){
var counter = 0;
return function(){
counter ++;
if(counter > frameRate/1000){
counter -= frameRate/1000;
draw();
}
}
})();
setInterval(frameCounter, 1);
This has been resolved in iOS 9.3 New meta tag option
<meta name="viewport"content="width=device-width,shrink-to-fit=no">

How to achieve a scrolling effect similar to the Paragon site

I don't know what this scrolling effect is called so don't know how to search for my answer, and I can't find it in the source code. What is the code responsible for the scrolling effect at Paragon where scrolling will cause the page to scroll down to the next div I assume. Or down a certain height.
I've thrown together a CodePen. It hase no animations but explains the general mechanics (the Paragon site does it differently but to start the following might be better suited).
The core part is this:
window.onwheel = function ( e ) {
e.preventDefault();
var wDelta = e.deltaY > 0 ? 'down' : 'up';
if (wDelta === "down") {
// scroll Down
} else {
// scroll Up
}
}
To know where to scroll we'll of course need to know where we are. There are several ways to do that. What I did is check the current top of the viewport against it's height.
var offset = window.pageYOffset,
viewportHeight = document.documentElement.clientHeight;
switch (parseInt(offset/viewportHeight,0)) {
case 0:
// we are in the first viewport
break;
case 1:
// we are in the second viewport
break;
...
}
I just checked it for functionality. Performance wise it can be improved upon. You should also bind keydown (to catch pageUp, pageDown, space and so on) but it can be done in a similar fashion. To ensure backwards compatibility you'll need to expand the code (e.g. a binding to the onmousewheel event). But this will give you a place to start.
PS
Also consider what behaviour you want when reloading the page (if the user reloads while between viewports it will stay between them until another scroll occurs).
This answer could also interest you.

Switch tabs based on mouse scroll

I would like to have a widget on a webpage containing a number of tabs. When the user scrolls the page and the widget comes in to view and he keeps scrolling down, the tabs should be activated one by one (without the page scrolling further down). Once the last tab is showing, the page should resume scrolling as usual. Is this doable using JS/jQuery?
UPDATE:
Since this seems too broad a question:
The problem is, I don't know how to use the scroll offset and prevent the page from scrolling down until I decide it can resume its normal behavior
UPDATE 2
I created This fiddle,
$(document).ready(function(){
$('#tabbed').mouseover(function(){
$(this).focus();
}).scroll(function(){
console.log("scrolling tabs");
});
$(window).scroll(function(evt){
var scrollPos = $(this).scrollTop()
console.log(scrollPos);
// BULLETPROOF WAY TO DETECT IF THE MOUSE IS OVER THE
// SCROLLABLE DIV AND GIVE IT FOCUS HERE?
});
});
it contains a long page and a scrollable div among its contents. The only problem is that the div starts catching scroll events only if I move my mouse. If I could find a bulletproof way to activate the scrolling div whenever the mouse is over it I'm there. Any ideas?
You can't prevent scrolling with javascript. Using iframes and divs with scroll will only work if the mouse is over them.
You can cancel the mouse wheel and keys events related to the scrolling, however the user will be able to scroll using the scrollbar (more here).
Another approach is leaving an empty area and fixing your widget inside this area, like in this working example
$(window).bind('scroll', function()
{
var scroll = $(window).scrollTop(),
innerHeight = window.innerHeight || $(window).height(),
fooScroll = $('#fooScroll'),
emptyArea = $('#emptyArea'),
offset = emptyArea.offset(),
fixedClass = 'fixed';
if(scroll > offset.top)
{
if(scroll < offset.top + emptyArea.height() - fooScroll.height())
{
fooScroll.addClass(fixedClass);
fooScroll.css("top", 0);
}
else
{
fooScroll.removeClass(fixedClass);
fooScroll.css("top", emptyArea.height() - fooScroll.height());
}
}
else
{
fooScroll.removeClass(fixedClass);
fooScroll.css("top", 0);
}
});
Then you can change the tabs while the page is scrolling.
You should be able to do this. You can use the jQuery scroll event to run your own code whenever the user scrolls up or down. Also, so long as you call e.preventDefault() whenever the scroll event is fired, you can prevent the whole window from scrolling up or down.

Window scroll event causing IE to lag badly, when using mouse wheel

I have a navigation container near the top of the page that should add or remove the classname "stuck" (switching between position:static and position:fixed) when the page scrolls beyond a certain value. Seems to work fine in FF and Chrome, but of course IE (7,8 and 9) is having trouble.
The page lags heavily (essentially unusable) when scrolling using the mousewheel, although if I grab and drag the horiz scrollbar then the page slides smoothly with no lag.
My searching around revealed that it's probably because IE executes way more scroll events than the other browsers, but I can't figure out exactly how to throttle the number of events being fired. You can see in the code block below that I'm also using a 'scroll stop' solution but I really need to also be able to execute a callback WHILE the user is still scrolling when they go beyond a certain point on the page.
I thought the way I was implementing it was pretty and stripped down and basic, but is there a better way to handle this, at least just for IE?
var scrollValue = 0;
var scrollTimer = false;
$(window).bind('scroll', function(){
scrollValue = $(window).scrollTop();
// SET TIMER DELAY FOR SCROLL-STOP
if (scrollTimer) {
clearTimeout(scrollTimer);
}
scrollTimer = setTimeout(scrollStopped, 25);
// STICK/UNSTICK HEADER
if (scrollValue > 320){
if (!$(stickyWrap).hasClass('stuck')){
$(stickyWrap).addClass('stuck')
}
} else {
if ($(stickyWrap).hasClass('stuck')){
$(stickyWrap).removeClass('stuck');
}
}
});
Down with timeout, up with switch
If you made the jQuery a little more simple, and added a switch to only execute anything once before and after the threshold, it should speed things up nicely.
var header = $('.stickyWrap'),
trig = 320,
go = true;
$(window).bind('scroll', function(){
var scrollValue = $(this).scrollTop();
if ((go && scrollValue > trig) || (!go && scrollValue <= trig)) {//before or after
header.toggleClass('stuck');//toggle class
go ? go = false : go = true;//toggle boolean
}
});
Now it will only try to execute anything only once before and once after it crosses the threshold of 320.
Made A Fiddle >

Categories