Delay on resize event on virtual keyboard on iOS Safari - javascript

I'm working on an a webapp, where I need to adapt the contents of the screen when the virtual keyboard is expanded. Luckily, someone has already created an example of this here:
https://pmusaraj.github.io/ios15-bottom-bar2.html
When tapping on the text area, it correctly resizes. However, there is a small delay between the tap and when the resize happens in iOS 15.5. This is because the resize event doesn't seem to fire fully until after the keyboard is expanded. In iOS Chrome, interestingly, this does not happen and it works correctly.
Are there any workarounds to get Safari to fire the event sooner? Or alternative approaches to achieving a similar effect?

As of today there are no real solutions for this.
The only "workaround" that I found is to detect when the keyboard opens and closes with regular events like focus and blur. But you can't guess the final visualViewport sizes because there are different keyboards so this wasn't an option for me.
My "solution" to this issue was extend the modal and its background fade beyond the viewport with after elements (see here). That way there is still a jump between opening and closing the keyboard, but at least the look is a bit more consistent.

Related

Is it safe to toggle bottom menu based on initial window.innerHeight value?

The question
When window.onresize event is fired, the bottom menu should become hidden if window.innerHeight is smaller than it was at window.onload.
Will this behave consistently across mobile browsers and operational systems?
Rationale
This is the solution I found to deal with the fact that mobile keyboards resize the viewport when they come out. If the bottom menu is not hidden when the keyboard comes into view, it will get stacked upon the keyboard.
This solution works as expected on Chrome v80 running on Android 7.1.
I wonder, however, if the below cases are common, since they would brake the mechanism:
Browsers that won't trigger the resize event when the keyboard comes in and/or leaves
Systems/browsers that keep the keyboard visible while navigating to a new page, therefore making the initial window.innerHeight value different from the actual viewport size without keyboard
Important: Doing the toggling through Input focus/blur events is out of question. I've found that on my Android phone, when the System's go-back button is pressed, the keyboard hides, but the input does not lose focus, therefore the bottom menu stays hidden.

How to detect Android Split Screen Resizing from Web View?

We are working on a webpage that is currently having issues with split screen resizing.
When we change the orientation of the page on a mobile browser or do a window resize on a desktop browser, we are able to run the required updates fine because we listen to the resize and orientationchange events that get fired with either type of event.
However, we just realized that with split screen on Android (and possibly split screen on iOS tablets), we aren't triggering any resize events for the window and therefore can't do proper updating of our elements based on the split screen being activated or updated (when the user moves the split).
Is this something we can work around or am I just completely missing some functionality that I should be using?
I have looked around online and haven't found anything related so far that I could use from our JS.
Thanks! Any pointers would be greatly appreciated.
Information about Multi-Window Feature in Android - doesn't go over any possible ways to detect it from a web view though, but looks at it from an Android app dev perspective

Firefox, touch events and "smooth" scroll behaviour – results in no scrolling

I'm at a loss as to what is going on here.
Please refer to the CodePen: https://codepen.io/ilmiont/pen/jJjgPw?editors=1111
Swiping with a touchscreen should smoothly transition the screens up and down, using the "smooth" scroll behaviour.
This does work exactly as intended with Chrome.
Firefox... just doesn't scroll. Yet the touch events are being fired, and "Next" / "Previous" is being logged to the console. But the scrollIntoView(...) call does nothing when invoked with {behavior: "smooth"}.
If you click the button, the scroll behaviour is changed to auto (no smooth scrolling)... and this works without any issues in Firefox.
What have I missed? Why is Firefox not scrolling at all when smooth scroll behaviour is used, even though it seems the swipes are being detected correctly?
A further oddity: the demo doesn't work in Chrome in CodePen either. Copy the HTML/CSS/JS into a new document (right-click CodePen viewer, "view frame source") and run directly in the browser, and it works exactly as intended, with smooth scrolling within the pages.
I think I must have missed something, and the CodePen issues in Chrome are interesting, but I just can't see what right now.
Chrome... just works... except in CodePen.
Firefox... everything looks like it should work, but the scrolling never occurs.
This has taken me far too long to figure out, but here's the solution which finally works:
Use passive event listeners!
In the original pen, I was doing {passive: false} and then calling preventDefault(...) on the touchstart and touchmove events.
It turns out, that this isn't necessary to achieve the desired effect.
Using the passive listeners results in everything working as intended in Firefox.
I still consider the original behaviour is odd; further investigation revealed there seems to be a timing issue in Firefox. In the swipe(...) method, adding a 250ms timeout to the dispatchEvent(...) call results in everything working as intended also – it seems as though the touch handlers can continue to block/throttle scroll events past when they should have been removed.
Will keep investigating but I have a solution for now.
(Edit – forgot to mention, when using passive listeners, also set touch-action: none on the target.)

jScrollPane on touch devices - drag button is in reverse

I've implemented jScrollPane and I'm having an issue on touch devices.
The example I'm using is http://jscrollpane.kelvinluck.com/drag_size.html where I have a vertical scroll using a circular button image for the scroll on the track. The class that's added to this is jspDrag.
On desktop, when you click and scroll the vertical button, it drags down and the content scrolls up, which is natural in my eyes.
The issue I'm facing is on touch devices (check the example URL above in Chrome using iPhone/iPad emulation in dev. tools) where you can't actually drag the button down - you actually have to scroll it up for the content to scroll?!
Users are definitely not going to know this as it's a button rather than a content block that you're using as a control.
I'd like to be able to touch and drag the button down on touch devices, rather than up, to make the content scroll.
Has any one come across this issue and managed to solve it? I've searched SO and Google Groups with no luck.
Thanks.
Unfortunately jScrollPane seems to just work like this, with an annoying caveat, which is unfortunate - I really liked the plugin.
I came across http://manos.malihu.gr/jquery-custom-content-scroller/ which functions the way it should and runs super smooth on touch devices.

Scroll event on Android Browser not firing. Need workaround

I've created a website with a parallax street scene. See here for an archived version.
It works just fine on all major desktop browsers, and Safari Mobile. It works fine in Mobile Firefox and Chrome for Android Beta also. However the default Android browser has issues with the scroll event. Let me be clear. Scrolling is not the issue. The div scrolls as required. The scroll event doesn't fire. This issue I experience on Honeycomb as well as ICS.
I'm not concerned about other mobile browsers because for mobile screen sizes one usually does not see the parallax scene; mediaqueries and conditional JavaScript loading take care of that. Responsive design and all that jazz.
Basically, I've written a parallise() jQuery plugin that positions each image based on its position and 'depth'. This function is bound to the scroll event.
On Android Browser, this event only fires at the start of the next touch, instead of continuously.
OK, so I thought that perhaps if I bound the function to touchstart, touchmove, and touchend events I would solve my issue. No cigar. Other touch events are also bugged. Applying the suggested workaround causes the events to fire, but as I have to e.preventDefault(), scrolling (the whole point of the exercise) is disabled.
What if I just poll the position of the stage div relative to the window div? Turns out that the position information is only updated at the start of the next touch.
I am at the end of my tether. Any help would be much appreciated.
Even if the touch events worked correctly on the bugged versions of Android, and you were then effectively able to track the native scroll position during a drag, this would be prone to error. For example, it wouldn't account for the momentum animation which happens after the touching has finished.
iOS and Android make sacrifices to improve the performance of scrolling. On both platforms, it's not possible to get the accurate scroll position until the scroll has completed. The scroll event (on the <body>) doesn't fire until the momentum animation is finished. So while your original question is about scroll events on an overflowing <div>, fixing this might not be totally helpful for you anyway.
If you want an animation to update in time with the scroll, then you need to perform the scroll programatically rather than using the browser's native scroll. The best library to do this is iScroll. You can achieve parallax effects very easily as seen in this demo.
If you need more complex effects (the walking character, in your example), you can opt for the "probe" version of iScroll which allows pixel-perfect polling of scroll position in return for reduced performance.
However, there are many downsides to using iScroll:
You may need to change your markup and styling
It is unnecessary overhead for desktop browsers, but due to markup changes may be difficult to use only as a fallback
The scrolling will not feel perfect - on iOS, with its usually excellent scrolling performance - the slight difference in momentum calculation can feel jarring. On Android, the scrolling can become more laggy than usual.
Swipe shim that doesn't need preventdefault on touchstart: https://github.com/TNT-RoX/android-swipe-shim

Categories