Jankiness with Chrome mobile's autohiding toolbar and full-height divs - javascript

I have a div that is resized to be at the full height of the viewport on load as well as on resize. The problem that I am having is that on Google Chrome for iOS (I haven't checked Android, but I can imagine that it displays the same erratic behaviours) if I scroll down, as usual the address/tab bar scrolls up. And as it does, it fires resize events. When that happens, the div and its contents jitter and cause scrolling to be come sluggish, as well as causing other oddities with the div below.
JSFiddle: http://jsfiddle.net/mseymour/9PEC4/

I would suggest setting the height of the .home-hero only once on an smartphone, by either checking the height of the window (could cause problems, it's inconstant) or user agent sniffing.
Here are some links:
http://detectmobilebrowsers.com/
What is the best way to detect a mobile device in jQuery?
Detecting a mobile browser
Then set the height only once since on a mobile you cannot really resize the window, and you don't need to resize it on every resize event.
if (isMobile) {
fullScreenSlide(); // resize once
} else {
setResizeEvent(); // Set the event for multiple resizes
}
function setResizeEvent() {
$(window).on("resize", function () {
fullScreenSlide();
}).resize();
}
function fullScreenSlide () {
var browserheight = Math.round($(window).height());
$('.home-hero').height(browserheight);
}
You want to do as little "things" on a smartphone since smartphones are really slow performance wise compared to a desktop

Related

wheel Event Reliability

I'm working on a web project that has animations and page changes on the scroll ( specifically, scroll direction ) and I've been looking for multiple possible good and reliable solutions.
I've been detecting the scroll direction by detected the window's scrollY with the user's previously saved scrollY that I have saved in a variable. The only problem is that the scroll event doesn't fire when at the top or the bottom of page, even though the content is all absolute/fixed positioned.
I want to turn to the wheel event because of its deltaY values from the event, and it still fires when at the top of bottom of the page so I can remove the scrollbar and keep the body of the page 100vh.
The Mozilla dev docs say:
Don't confuse the wheel event with the scroll event. The default
action of a wheel event is implementation-specific, and doesn't
necessarily dispatch a scroll event. Even when it does, the delta*
values in the wheel event don't necessarily reflect the content's
scrolling direction. Therefore, do not rely on the wheel event's
delta* properties to get the scrolling direction. Instead, detect
value changes of scrollLeft and scrollTop of the target in the scroll
event.
(https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event)
And I'm also curious if the wheel event will work correctly on mobile with touch?
Here's a good example of what I'm trying to replicate: https://reed.be
There is no scrollbar, yet things still happen based on your scrolling.
CanIuse shows full compatibility of the wheel event with modern browsers, and some older versions.
see here -> https://caniuse.com/#feat=mdn-api_wheelevent
I've found a solution that references the wheel event (How to determine scroll direction without actually scrolling), though my question still applies -
How reliable is the wheel event across devices and browsers, including mobile?
I am limited to my own current version browsers and android devices for testing.
You can fool the browser by setting the additional height on the body to match the content width and setting the overflow to scroll. Then use some basic script, to set the scrollLeft property of your container to equal the window scrollY.
You will need to set the height of the body equal to the total width of the panels.
body {
height: 400vh; // 4 panels of 100vw each
...
}
.panel {
width: 100vw;
...
}
JS
const viewPort = document.querySelector('#viewport');
let lastScroll = 0;
window.addEventListener('scroll', (e) => {
let scrollY = window.scrollY;
// scroll the container by and equal amount of your window scroll
viewPort.scrollLeft = scrollY;
lastScroll = scrollY;
});
Rough JSFiddle Demo

$(window).resize() in safari : why it works also if scroll window (but doesn't resize)?

i noticed, with safari on my iphone5 that
$(window).resize()
it works strangely...
i have this code:
$(document).ready(function () {
$(window).resize(function() {
avviaChart();
initialize();
if($('#time').is(':checked')){
$("#time").removeAttr('checked');
$("#Time").css('border','2px solid #ffffff');
}
});
});
this code should work only when sizes of window change....
with other browser work very good, but with safari the code works also if i scroll the page (and the sizes of window doesn't change)...
HOW IS POSSIBLE ? O.o
This is a known bug that happened from iOS6 Safari. The resize event fires randomly while scrolling. Fortunately it's not a jQuery issue.
This answer to a similar problem might solve your issue as well.
For the lazy:
3Stripe posted that you should "Store the window width and check that it has actually changed before proceeding with your $(window).resize function"
His code snippet:
jQuery(document).ready(function($) {
/* Store the window width */
var windowWidth = $(window).width();
/* Resize Event */
$(window).resize(function(){
// Check if the window width has actually changed and it's not just iOS triggering a resize event on scroll
if ($(window).width() != windowWidth) {
// Update the window width for next time
windowWidth = $(window).width();
// Do stuff here
}
// Otherwise do nothing
});
});
As you see, in iphone/ipad and android devices, when you scroll down the page, address bar will be small and when scroll to top address bar size will be return to the actual size, this operation fires window.resize event
This issue specific to ios, if any handler which changes size of anything in window, will trigger resize event, and sometimes it will get stuck in infinite resize call. So as mentioned above, have one condition which compares previous width with current width if both are equal then return.

iPhone Web App - Prevent keyboard from moving/push up view - iOS8

In all versions prior to iOS8, I was able to prevent the iPhone keyboard from pushing up (and destroying) my html/css/js view when the keyboard appeared by the following method:
$('input, select').focus(function(event) {
$(window).scrollTop(0);
// or via the scrollTo function
});
Since iOS8, this no longer works. One workaround is to place this code within a setTimeOut
setTimeout(function() { $(window).scrollTop(0); }, 0);
But it only makes the view do a jerky motion as the view is initially pushed up by iOS, then dragged back down by my js code. preventDefault and stopPropagation does not help either.
I've tried everything available on the web of course including my own solution posted here: How to prevent keyboard push up webview at iOS app using phonegap but so far, nothing works for iOS8. Any clever ideas on how to prevent the keyboard in iOS8 to push/move the view?
Try position:fixed on body, and/or wrap content in a div and position:fixed on it as well.
There are some options :
Make listener on your ios code, to move the screen up along with the keyboard height, so everything move up along with the keyboard, then your design save.
Make your css design responsive. Then no problem with change height, it will be scrollable inside your webview.
When keyboard pushes up view in iOS, a scroll event is triggered ($(window).scrollTop() is changed). You can put $(window).scrollTop(0) inside the scroll event handler. To prevent the jerky motion, set opacity to 0 during scrolling. Related codes may look like this:
function forceScrollTop() {
var scrollTop = $(window).scrollTop();
if (scrollTop != 0) {
$(window).scrollTop(0);
$(selector).css('opacity', 1);
$(window).off('scroll', forceScrollTop);
}
}
// when an input is focused ...
$(selector).css('opacity', 0);
$(window).on('scroll', forceScrollTop);

Simultaneous double frame scrolling fails in FF on OSX and Win. w/ JSFiddle

I'm trying to achieve a simultaneous menu/content scrolling, like on www.urplay.se. The following code is very slow in Firefox (Win & OSX) but works in all other desktop browsers. Any idea how to improve in FF?
Update: Fiddle, http://jsfiddle.net/2rCPD/
Update: the problem only occurs when scrolling with a mouse. A macbook trackpad works fine. Also, the scrolling is only slow when both divs are scrolling. Try it in the fiddle: when the blue left content stops scrolling, the red right content starts to scroll at normal speed.
function initiateDoubleScroll() {
$document.on('scroll.doubleScrollNameSpace', function () {
$myMenu.scrollTop($document.scrollTop());
});
$myMenu.on('scroll.doubleScrollNameSpace', function () {
$document.scrollTop($myMenu.scrollTop());
});
}
$myMenu is the left side wrapper div (look at urplay.se). The wrapper div extends full window height and has "overflow-y: scroll".

Interrupting Mac Smooth Scroll With Javascript

I have a script that monitors scrolling and takes control of the scrolling to animate the page based on certain parameters. To do this, it calls window.scrollTo(0, currentScrollTop); which perfectly interrupts the smooth scrolling in Firefox on Windows. I can then animate the page scroll to the place where I want it.
Unfortunately, this trick doesn't appear to work in browsers in MacOS which results in a broken experience as JavaScript and the browser compete to scroll the window.
Is there a cross-browser way to stop smooth scrolling with JavaScript?
Site using effect in question: http://capitalismis.com
Relevant (simplified) code:
$doc.on('scroll', function(e)
{
$doc.off('scroll');
window.scrollTo(0, $doc.scrollTop());
var aniSpeed = 1500 * Math.abs(scrollTop - selected.top) / windowHeight;
$body
.stop()
.animate({scrollTop: selected.top}, aniSpeed, 'easeOutQuad');
}
);
In short: don't try to override native scrolling. Every OS and device handles things differently and it's impossible to predict the different scenarios. There is "hard scrolling" (most Windows versions), "soft scrolling" (≈Mac OS X 10.6+) and browsers that only fire the onscroll event when the scrolling is completely done (iOS). It's a mess.
Instead of trying to modify the scrolling behavior of the body, I would modify the elements of the page accordingly. Listen to the onscroll-event, and move things around on the web page.
// Capture scroll event
$(window).scroll( function() {
// Get scroll offset from top
var scrollTop = $(window).scrollTop();
// Use it to move elements around on the page (or change backgrounds etc.)
// Here: move .element in the opposite direction of the scroll
$('.element').css({
'-vendor-transform' : 'translate3d(' + (scrollTop*(-1)) + 'px,0,0)'
});
});

Categories