Scroll events stop working in Safari - javascript

I am developing a website that has scrolling transitions on the "index" page and then normal scrolling with a sticky navigation bar on other pages. The site also uses ajax to transition from one page to the next. I have an if statement based on if the user is on the index page use the scrolling transitions, else use normal scrolling with the sticky navigation.
The problem I've found is that in safari when I click on a link from the index page, scroll on the new page and then go back to the index page, the scroll transitions are not activated again. In fact it seems that the scroll events I have set up stop working entirely.
However this problem does not occur in any other browser: Chrome, IE, Edge or Firefox.
I don't know if it's best for me to post the code for it on here because it is a bit long. But here is a link to the code: http://www.dreshaddev.dreamhosters.com/layout/js/scripts.js
Here is a link to the development site: http://www.dreshaddev.dreamhosters.com/layout/index.php
I have tried multiple solutions like reinstating the same code after an ajax call and removing event listeners and re-adding them back in. I'm not sure what to do. I am testing this on Safari 9.1.3.

Related

Display loading indicator when navigating away from page on Safari

I would like to display a nice page transition when navigating between pages on a site.
I've tried using these events: beforeunload unload pagehide and also visibilitychange.
There was a webkit bug described as
visibilitychange:hidden doesn't fire during page navigations
And a workaround is listed:
using the pagehide event is the workaround
I am adding a class to the html element on these events. On Chrome and Firefox this activates my loading indicator class and the animation is displayed until the page is replaced. I get a nice loading transition between page navigation. So, in Chrome and Firefox, everything works great.
Unfortunately, I am not having any luck with Safari on iOS (iPhone or iPad) and also failing on macOS Big Sur Safari. I found a related question here: Safari change dom on before unload page however, it only discusses the beforeunload event. I am hoping that by being less specific here that a viable alternative pops up.
I have tested the css works on Safari by manually applying it and also verified my listeners are called on Safari via the javascript console. However the css change doesn't seem to be rendered. There is no transition shown on the page being unloaded before getting the new page response from the server. I've also verified it isn't related to the CSS in use by setting a simple background color without any transition or similar effects.
So far, the only way that I have been able to get Safari to render the dom change is by returning a truthy string on unload - but this prompts the user if they want to leave or not which is not my intention.
I want to avoid browser detection - however the last viable alternative I can come up with is scanning the dom for anchors, buttons, forms, etc when Safari is detected to enable the loading indicator before navigating.
Are there any other options to consider?

CSS keyframe animation not triggering when using back button on iOS device

I am running a keyframe animation on the body element of my page that fades in and out the opacity of the background. The fade in animation is run directly on the body as a CSS rule, and the fade out is triggered by setting a class to the body element, when special links a clicked. The implementation works great on Android Chrome browser, and desktop Safari, Chrome, Firefox, IE11 and Edge.
The fadeout animation also works great when I click a link from an iOS device, but once I use the native back button in Safari it seems that the page just goes back to a previous view that it saved of the last page, without running the fadein animation again. Therefore the page looks broken.
How can I handle this? can I somehow force the iOS device to reload the page when I navigate back? or Would there be another way to handle it?
Safari does not "reload" the page when you hit the back button. One common workaround is to add some code to the footer of the page to tap into the pageshow event. You could then do something like.
const reloadAnimation = () => $("#my-element").removeClass("run-animation").addClass("run-animation");
window.addEventListener('pageshow', reloadAnimation)

Videojs requestPictureInPicture() works only once on scrolling to top and bottom

I'm using Videojs Framework to show video on a page, but there is a problem with PictureInPicture functionality. I'm trying to go in PictureInPicture mode automatically when user scrolls down, and again when user scrolls up (back to the actual video player) exit the PictureInPicture mode.
The first time I scroll down and up it's all working, but any attempt after that fails.
Here's a pen to my code: https://codepen.io/madefortestonly/pen/GRJxMya?editors=1011
This is the error message I got from the catch block:
DOMException: Failed to execute 'requestPictureInPicture' on 'HTMLVideoElement': Must be handling a user gesture if there isn't already an element in Picture-in-Picture.
at Html5.requestPictureInPicture (https://vjs.zencdn.net/7.6.6/video.js:22669:23)
at Player.techGet_ (https://vjs.zencdn.net/7.6.6/video.js:26085:34)
at Player.requestPictureInPicture (https://vjs.zencdn.net/7.6.6/video.js:26787:21)
at Player.<anonymous> (pen.js:75:16)
at https://vjs.zencdn.net/7.6.6/video.js:4530:9
By the way, someone seemed to have exactly the same problem as I had in here:
Why video.requestPictureInPicture() works only once?
It looks like you need to click on the page for scroll to work for the next attempts because scroll is not part of the user-trusted events.
I tried to simulate a click with javascript on scrolling up but so far no luck.
How can I fix my code to automatically go PictureInPicture back and forth on scrolling without telling the user that he/she needs to click somewhere on the page?
You can't get around this, as you can't forge user interation. An alternative implementation, like reszing and repositioning the player within the page, might be a better option for your use case than the browser's native PinP.

JavaScript event to detect browser-side scrolling reposition on hash URLs in Firefox and IE Edge on Windows

While trying to tweak some scrolling script to perform "jump to" links on some pages, I noticed that if you have a page with contains a hash tag in the URL, the behavior is different depending on the browsers when you press enter on the address bar, after the page is loaded.
For example, if you load a page with an has in the URL and then scroll away from the target element, I noticed that on Firefox and IE, if you put your cursor on the address bar and press enter, the page will move back to the HTML element having the same id attribute as the hashtag but the page will not be reloaded.
I also noticed that neither popstate nor hashchange events are triggered in such scenario. The scroll event will most likely be triggered but how can we know this is not the user scrolling but the browser reseting back its position?
Is there any was to detect this type of event in the browsers? Given this is outside the viewport I'm a bit curious. But I have a scenario where I would like to reposition the menu depending is the page is scrolling up or down.
To try to explain what I'm looking for:
Page with hashtag #test and element <div id="test">
Press F5, the page posisition itself right where the <div> is
Scroll up or down
Go on the address bar and press enter
---- Looking for an event to detect the previous action ---
the page posisition itself
right where the <div> is
Example in JSBin (open in Firefox):
http://jsbin.com/rifikereze/1/edit?html,js,output
Output:
http://output.jsbin.com/rifikereze/1#test2
Open your console in Firefox
Make sure in the Firefox setting you enable "persistent logs" to keep logs after page reloads
Press F5 (you should see a console message "reloaded")
Now try to move the page, put your cursor in the address bar and press enter
You will see the page does not reload
How can we detect these events (other than scroll events)?
Make sure to use Firefox on Windows if trying to reproduce. It looks like other OSes have other behaviors.
Given the lack of answer, my presumed answer is No.
There is no way to detect re-positioning of browsers using fragment identifiers (aka hash) in URLs and the address bar.
On top of this, browsers seems to have inconsistent behaviors:
Firefox on Linux behave differently than on Windows (it reloads the page).
Chrome seems to be ignoring re-positioning unless the page's position is set back to the top position before unloading.
There seems to be no standard across browsers on whether the normal behavior is to reload or re-position.
The only safe way to detect fragment identifiers repositioning is when loading the page.

Trigger scroll in Opera mini

How to scroll down or up to specific Y-px position in opera mini mobile browser on the page without using any 3rd libraries just pure js? Tried everything possible from scrollTo to SCrollInto View nothing works. Help please.
The scroll behavior is true as in every modern browser.
When you just open the new window/tab and don't touch screen the javascript scroll API via window.scrollTo(x,y) works fine because you did't signaled the browser where do you want to scroll.
But if you init scroll event (for example swipe) when your page loading the browser will ignore javascript scroll API for example scrollTo. And if you will refresh the page the javascript scroll API will be not work. Because it's a good practice to return user on that page place where user was before refresh.
Also hash bookmarks can scroll the page. If you set a #bookmark to the page URL, the page will scroll to bookmark until you scroll the page. And then you scroll all will be like I wrote upper: javascript scroll API will be ignored.
But there is one way to scroll in any case - manipulate with hash bookmarks:
window.scrollTo(0, 500);//will not work if the user scroll the page
location.hash = '';//reset hash
setTimeout(function () {
location.hash = 'bookmark';//will scroll to bookmark in any case
}, 1000)//remember about operamini timers limit
It works so because use must control the page, not it's code.
From the Opera doc, below the Unsupported DOM events section you will find:
As you can see, key events such as keypress and keyup are not
supported. Neither are touch and scroll events.
So scroll events are not supported in Opera Mini. See Other References

Categories

Resources