Is there a cross browser event for activate in the browser? - javascript

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

Related

Detect Page Refresh or Navigation in Browser

I have a web app where a parent page displaying a list of records opens up a new tab ('child') to edit a clicked-on record. I want to track who has a page open, so I can display a message if more than one person is editing a unique record. This means reporting when a page is closed. I have assigned each page a GUID to facilitate recognition of the page instance.
So javascript in the browser needs to detect several scenarios:
browser tab closed
browser refresh
browser navigation to hyperlink
browser navigation forward/back
At the moment, all of these appear to trigger the window.onbeforeunload event. However I use this event to warn of changes in the underlying data, which means the event returns the confirmation text, and there is no way of knowing in this event if the user subsequently confirms or cancels the page unload. So I can't use this event to track page closure.
According to a number of sources the window.onunload event should be triggered in all of the above scenarios (and if it was, I could use it), but testing under Chrome on Windows is only triggering this event in scenario 1 (when the tab is closed). It works fine for that.
I'm pretty surprised by the lack of information around this - surely it's a bread and butter requirement in modern sites?
Has window.onunload been deprecated lately in some scenarios, or in some scenarios in some browsers? Without a reliable hook that takes place when the page is about to be replaced with some other information, it's impossible to monitor closing of a page. Any other workarounds?
I know that the two unload events suppress blocking functions (such as alerts) in the handler. However they appear to do hit breakpoints, do a console.log and allow Ajax calls just fine. I'm pretty sure they are not being fired in events 2,3 and 4 - it's not just that my debugging is being blocked.
While there appear to be answers on SO already (most of which don't work or are deprecated), I posted this because browser events are a shifting-sands scenario as security issues evolve, so I wanted to find out where we are in 2021.
Actually, it looks as if this might be the solution: https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event
Google discourages use of the unload event because it is (a) unreliable on mobiles and (b) blocks the caching of pages. It is also advised to only add the beforeunload event just before it is used, and to remove it afterwards, because it also blocks the caching of pages (I note that this is not really practical for me, however, as I use it to guard against unintentional closing of a page after a possibly significant amount of data has been entered, and this could happen at any moment).
So as of July 2018, and still best practice as of July 2021, this would be the recommended way to detect the unloading of a page:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
addEventListener(terminationEvent, function(event) {
// handler code here ...
}, { capture: true });
This has been tested in a small ASP NET Core project using an AJAX callback to report the page termination, and appears to work reliably in Chrome and Edge. Also works in IE11 as long as
<meta http-equiv="x-ua-compatible" content="IE=edge">
is present.

Problem with opening new tab in a browser

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.

Can't focus elements on load in Chrome - very weird bug (in Chrome?)

I have a very, very weird issue that only seems to be an issue in Chrome.
When a user comes on the website, the user cannot focus any element (via mouse click, if they focus it via tabbing, the elements don't get the 'focused' state either) and that's only an issue in Chrome. That is, until the user resizes the window, minimizes the window, opens a new tab, opens developer tools, etc. Reloading the page does nothing. However, as soon as focus is "enabled", the user can navigate/refresh with purging cache, etc., close the browser and open it again, and everything works normally - the elements get the 'focused' state normally.
This behaviour can only be reproduced in Chrome and not on localhost.
The difference between localhost and beta environment is:
beta env requires authentication (basic http auth)
files in development env are concated in a single JS and single CSS file and both are minimized
beta env includes hotjar, while there's no hotjar on localhost
There are no custom event listeners that would listen for the 'resize' event. There are no errors in console and all javascript that doesn't depend on focused element state gets executed correctly. Hover events and all CSS styling that depends on hovered state all work correctly.
The main issue is, that a form which has to be filled out and includes a datepicker, cannot be filled out and thus the users can't really interact with the page. Datepicker doesn't open and, as the input elements don't get the focused state, they don't visually change (CSS :focused selector isn't working either) and thus give the impression to the user that they cannot type in the normal text inputs (which works, after clicking on the input, it is possible to type in the input).
I have tried removing hotjar and the problem persisted. The only thing that made the problem go away was removing the basic auth, however, that is not an option in this stage (it's a closed beta test, so we need to limit the access only to the users with password).
I also find it extremely odd that basic auth would interfere with the focused state of elements, especially as the error persists after you refresh and only goes away as soon as you interact with browser itself (minimize, open new tab, do anything that resizes your browser window or document), after that it works correctly and there are no errors whatsoever.
The problem only started to appear recently, but I do not believe it's an issue with the app itself, as I tried rolling back to a couple months old build and the problem persists. All of that makes me believe it's a bug in Chrome, but what can be done to fix it?
EDIT: I also tried to add autofocus property to an input element and, in beta environment, it doesn't get focused.
So it seems it indeed is a Chrome bug that's present both on mobile (Android and iOS) Chrome browsers, as well as desktop Chrome browser (tested both on a Windows and a Mac). I submitted an official bug report. In the bug report, a fellow user made a website that's accessible only through basic auth and only has 2 basic inputs, the input should get a red border on focus. As expected, after opening the webpage in Chrome (for ease of use - incognito mode), the input doesn't get focus and the border doesn't change.
For those who are also affected by this bug in Chrome, you can track the bug progress here: https://bugs.chromium.org/p/chromium/issues/detail?id=740652
Meanwhile, here's a hacky solution for those interested:
$(document).on("ready", function() {
var $inputs = $("input");
$inputs.off("click.trick");
if (!sessionStorage.fixedChromeFocus) {
sessionStorage.fixedChromeFocus = "true";
$inputs.on("click.trick", function() {
var win = window.open("/", "_blank");
setTimeout(function() {win.close()}, 1);
$inputs.off("click.trick");
});
}
});
The goal is to, somehow, interact with the browser outside of the current page, to make it somehow lose focus. You cannot use JS to minimize browser, cannot resize it, cannot open dev tools. What you can do, though, is open a new window. Of course, if you open a new window immediately, a pop-up blocker (as most people have it) will block it and the window itself (or rather your current tab) won't lose focus. Opening a new window can only be done as a reaction to a user event (without triggering potential pop-up blocker).
I also use some browser detection so the code will only be executed for Chrome and, using server-side conditioning, only for builds that include basic auth.
What the code does, quite self evidently, is that as soon as a user clicks on an input, it opens a new tab and quickly closes it, 1ms later. To prevent this from happening all the time, on every page load, sessionStorage, which gets cleared automatically after tabs from that domain are closed, is used (and we've already established that once focus starts working correctly, it will work as long as you keep your browser open).
The effect of this code is that the user will see a quick white flash the first time he clicks on the input, but everything will work correctly

Is there a way to detect if the browser window is visible to the user?

Is there a way to detect if the browser window is visible to the user? I know this has been asked before. However, the answers I have seen suffer from the following problems:
Using visibilityChange event. The problem with this approach is that (at least on a Mac) when one uses cmd+tab to switch between applications, this event is not fired.
Using onBlur and onFocus events. These solve the above problem. However, these also fire when a page's visibility does not change. For example, if the browser is open in one half of the screen and another application is open in the other half, then switching between these will cause these events to fire; even though the user has the browser window visible all the time.
Using onPageShow and onPageHide events - these appear quite useless for the task of visibility. For example, onPageHide does not fire either when the page is minimized, or when cmd+tab is used to switch to another application that occupies the whole window.
What is the ideal solution for checking whether the page is visible to the user given the above issues?
Thank you.
Could you use setIterval polling and document.hidden?
nice wrapper Visibility.js

Detect if browser has more then 1 tab/window open

So i am developing a quiz web application. And i wanted to add a setting that the administrator of the quiz could set that would make it so the user could only have 1 window/tab open while the quiz is being taken.
The reason for this is to make it so they cant goto like google and google the answer while the quiz window/tab is open. Of course they could always open a different browser and do it that way, but still thought it would be a nice feature to have for them to enable.
Now i dont know if this would fall under a security sandbox violation (and thus not be available at all) but since i only want to detect if another tab or window is open and not get actual information about the tab/window i am hoping that this is someway possible using javascript.
You can't, but a possible workaround would be to use the new HTML5 fullscreen API. You could use a setInterval function to regularly test that document.fullScreen == true to ensure that the user has not toggled off the full screen.
This only works in modern browsers, and it's trivial to work around if the user knows his way around the JS console, but it does seem to fit your requirements.
Note that all fullscreen API implementations are currently vendor-prefixed.
There seems to be viable alternative to the approach described below the line: using Page Visibility API, currently supported by all the modern browsers. This looks like far more reliable than listening for blur. There's one possible way to do it:
// on quiz start
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
console.log('Y U hide?');
}
});
The problem is that visibilitychange event is fired only when page goes from visible to hidden (and vise versa). It still lets user open two browser instances - one with the quiz page, one with any favorite search engine, for example.
While you cannot detect the number of tabs open, you can try to check when the user goes away from the quiz page with this trick:
$(function(){
$(window).blur(function() {
console.log('I see what you did here!');
});
});
Sadly, it'll also give you plenty of false positives.
Can't, and shouldn't, be done.

Categories