I've been refactoring some javascript.
Previously, I had an HTML element open to Fullscreen when the user clicked on another element.
Now clicking the latter element initiates a server-side verification, instead.
Once the server-side verification check passes, the page reloads with extra data confirming the user is verified.
N.B. When the page reloads, it does so with a non-negligible amount of extra markup, styles, scripts and vectors. The reason I am re-factoring in the first place is to avoid the need to download all these extra assets (and keep them in the background, on standby) unless and until the user authenticates themselves
The first thing I discovered is that I cannot have the page reload and then have the HTML element immediately open to Fullscreen, because - and this seems entirely reasonable from a UX perspective, Firefox reports:
Request for fullscreen was denied because Element.requestFullscreen() was not called from inside a short running user-generated event handler.
Essentially, unless the user pro-actively interacts with the page, the Fullscreen API will not run.
(In this scenario, the user pro-actively interacted with the page before reload, which is not the same thing.)
So, I thought about it and then added:
document.body.addEventListener('mousemove', () => myElement.requestFullscreen(), {once: true});
Nope. The Fullscreen API still doesn't activate.
To check that I wasn't making an elementary error somewhere else, I tried:
document.body.addEventListener('click', () => myElement.requestFullscreen(), {once: true});
Which does work.
So: some user-interactions will successfully fire the Fullscreen API and others won't.
I have searched through the WHAT-WG HTML Spec but I cannot find a list of events which represent explicit and pro-active user-interactions on a webpage.
Does such a list exist?
Which other events apart from click will successfully activate the Fullscreen API?
Which JS events apart from click will successfully activate the Fullscreen API?
A small number of events will successfully activate the Fullscreen API.
Almost all of these events either imply a user-click or directly reference one:
change
click
contextmenu
dblclick
mouseup
pointerup
reset
submit
touchend
Further to the list of click-based events above, the Fullscreen API may also be activated via:
ScreenOrientation.onchange
Source:
https://www.aworkinprogress.dev/request-fullscreen
Related
For some interactive graphics we are using canvas in our HTML page. Inside the canvas we have "link-like" controls to link users to external resources.
Because of canvas, we do NOT use <a href=""> tag, but we are opening new browser tab via JS code, like this:
this.pixiLayout.App.renderer.view.addEventListener('click', () => {
if (this.pixiLayout.externalUrl) {
window.open(this.pixiLayout.externalUrl, '_blank');
}
});
The problem:
Google Analytics(front end) show us much more clicks than actual "page views" analytics from third party resources, up to 10-20 times.
It means that users clicked on the link(and it recorded by GA), but by some reason, link was not opened, or opened but not loaded in a new tab.
I know about ad/pop-ups blockers. It could be a case for some percentage of users. But it is not a case for 90% of users, like we have.
And we could not reproduce this behaviour on any device we own.
Question:
Could it be caused by normal browser policy or restriction that could cause a blocking of new tab like in our case?
Could it be like "new feature" of modern browsers I do not know about yet?
Ok, the issue was in our own code. Event firing of GA(we use custom events) was implemented in the different place of the code than an actual action - window.open(). They were supposed to be called on the same user action - user click. But it was not a case, specially for mobile devices. When user tapped on that interactive, link-like control and moved finger up or down(for scrolling), it fired custom event responsible for tracking "the click". But actual "click" event is not fired in this case.
Conclusion: never ever do an actual action in one place and "collect analytics of that action" in another place of the code.
Is there any Out Of the Box Vaadin 10 (and higher) event similar to window.onbeforeunload in JavaScript?
I've tried to use onDetach() or beforeLeave(), but it only works inside UI, and when user reloads the page or closes the page it's not working.
You can use the approach described in https://vaadin.com/forum/thread/17523194/unsaved-changes-detect-page-exit-or-reload that was already suggested in a comment.
At the same time, I'd urge you to be really careful with beforeunload events since they are in some situations fired even though the user is actually not navigating away from the page.
The most common case is if the user clicks a link that starts a download. In that case the browser will fire the event immediately when the user clicks the link. Slightly later when the browser receives the response headers, it will discover that it's a download and not a new HTML page to display. The end result is then that beforeunload has been fired but the previous page is still kept running.
If you want to use the event for cleanup, then the best approach today is probably a combination of the unload event and then using the new-ish Beacon API for notifying the server that the user has actually navigated away. Integrating this into a Vaadin application will require slightly more JavaScript, but it has the benefit that it will actually work.
Is there a cross browser event that can be used to show a message to the user returning to their web page?
For example, a user has ten applications or tabs open. They get a new notification from our app and I show a notification box. When they switch to our tab I want to begin our notification animation.
The activate event is common on desktop applications but so far, on the window, document and body, neither the "activate" or "DOMActivate" do anything when swapping between applications or tabs but the "focus" and "blur" do. This event works but the naming is different and the events that should be doing this are not.
So is the right event to use cross browser or is there another event?
You can test by adding this in the console or page and then swapping between applications or tabs:
window.addEventListener("focus", function(e) {console.log("focused at " + performance.now()) } )
window.addEventListener("blur", function(e) {console.log("blurred at " + performance.now()) } )
Update:
In the link to the possible duplicate is a link to the W3 Page Visibility doc here.
It says to use the visibilitychange event to check when the page is visible or hidden like so:
document.addEventListener('visibilitychange', handleVisibilityChange, false);
But there are issues:
The Document of the top level browsing context can be in one of the
following visibility states:
hidden
The Document is not visible at all on any screen. visible
The Document is at least partially visible on at least one screen. This is the same condition under which the hidden attribute is set to
false.
So it explains why it's not firing when switching apps. But even when switching apps and the window is completely hidden the event does not trigger (in Firefox).
So at the end of the page is this note:
The Page Visibility API enables developers to know when a Document is
visible or in focus. Existing mechanisms, such as the focus and blur
events, when attached to the Window object already provide a mechanism
to detect when the Document is the active document.
So it would seem to suggest that it's accepted practice to use focus and blur to detect window activation or app switching.
I found this answer that is close to what would be needed to make a cross browser solution but needs focus and blur (at least for Firefox).
Observation:
StackOverflow has a policy against mentioning frameworks or libraries. The answers linked here have upvotes for the "best" answer.
But these can grow outdated. Since yesterday I found mention of two frameworks (polyfills) that attempt to solve this same problem here for visibly and isVis (not creating a link). If this is a question and answer site and a valid answer is, "here is some code that works for me" but "Here is the library I created using the same code that can be kept up to date and maintained on github" is not valid then in my opinion it's missing it's goal.
I know above should probably go to meta and I have but they resist changing the status quo for some reason. Mentioning it here since it's a relevant example.
The Page lifecycle API can be used to listen for visibilitychange events.
[This event triggers] when a user navigates to a new page, switches tabs, closes a tab, minimizes or closes the browser, or switches apps on mobile operating systems. Quote
Current browser support
Reference on MDN
I have a website with Facebook integration. The homepage has a few Like buttons, which are popular, and a login button, which is not. I'd like to attach an event to the Like buttons which will make them de facto login buttons - that is, in addition to everything Facebook is doing, I want to take the opportunity to request extended permissions for my app.
It doesn't work, and here's what I know about why:
I'm listening for clicks using the following call:
FB.Event.subscribe("edge.create", function (obj) { /* my callback */ });
The edge.create event is fired when Facebook FINISHES processing the click.
Facebook processes the click asynchronously, deferring during completion of a request-response cycle.
Javascript code executed after this async wait is not part of the same stack, and lacks the blessings conferred by the user action.
The means that Facebook provides to request extended permissions involves creating a popup window, and most modern browsers include a popup blocker which rejects the call outside of a stack triggered by a user action.
This chain leads to the result that handlers fired on edge.create are unable to request extended permissions. I can think of two classes of solutions:
Find a way to listen on the original click, rather than after Facebook receives the click, sends a request, receives a response, and finally fires the global handler
Find an alternate UI for requesting permissions that doesn't involve a popup
Nothing I've found in researching has shown me an easy way to do either of these. On solution 1, FBJS provides an addEventListener method, but as far as I can tell FBJS has nothing to do with my case (integration on a website that I own), so I can't use that to catch the click. On solution 2, Facebook's own documentation for FB.login says the following:
You should only call this on a user event as it opens a popup. Most browsers block popups, unless they were initiated from a user event, such as a click on a button or a link.
(Source: https://developers.facebook.com/docs/reference/javascript/FB.login/)
So I'm at a dead end, but it seems like a terribly artificial problem - does Facebook want me to be able to request permissions upon click of a Like button, or not? If so, what am I missing? If not, why are they implementing this restriction in the UI layer?
Facebook Like buttons exist inside of an <iframe>. As such there is no way for you to capture or intercept the button's click event, or even to have a click event on the <iframe> itself as far as I can determine.
Perhaps you could start the page out displaying your own buttons that look like Facebook Like buttons, and then you can handle clicks on those as normal. You could wire them so that on the first click they request permissions and then replace all your custom Like buttons with actual Like buttons.
I am using a forever frame (COMET streaming technique) and in IE6 whenever a user clicks on a link (to even just basic JavaScript method) the connection is immediately dropped and has to be manually refreshed.
Has anyone come across a similar issue and / or know how to address it?
How to address it: return false from your event handlers (event.preventDefault for listeners etc) so that the link is not followed and so no navigation occurs on a simple left-click. Put all your logic in event handlers attached from script (and not javascript: URL, which are a horrible fragile hack that should never be used).
Further: if it's just a button that does some scripting when clicked, and doesn't actually point to anywhere usefully navigable, it shouldn't be marked up as a link. Ideally it should be a button (input or button with type="button"), which you can then use CSS to style like a link rather than a button if you prefer.
(Another approach, that requires less styling work but has accessibility drawbacks, is to do what SO does and just put an onclick event on a <span> or <div>.)