Distinguish between focus loss inside and outside page? - javascript

A <div tabindex="-1"> element might have a focusout listener on it.
The event will fire whenever the focus changes to another element (or nothing) in the page.
However, it will also fire whenever the containing browser tab or window loses focus. This can be caused by a number of things: ALT+TAB, the WINDOWS key, the user mouse-clicking on another application, or the user opening the developer console.
When handling the FocusEvent, is there any way to distinguish between the event being fired due to focus change within the page or outside the page?
As an aside, FocusEvent.relatedTarget is available. However, it seems to be null both when focus goes outside the page and sometimes when it goes to another part inside the page (i.e. an element which cannot 'receive' focus as such). UIEvent.sourceCapabilities also seems to be available, and seems to reliably go null when the page as a whole loses focus, but I'm unsure how reliable this would be for solving this problem.
Any help would be much appreciated.

You could use the Page Visibility API to see if the window/tab has user focus
https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API

Related

How to lose focus on chrome extension popup window

I'm trying to implement following behavior. (1) User click the chrome extension popup icon (2) Extension popup shows up. (3) Extension popup lose focus without any user actions.
For the (1)(2) is easy, though I'm stuck on the (3).
Some options I tired:
a. Use vanilla JS for .focus() and .blur(). Though it requires binding element. Not the whole document. I don't have any control for this page user is visiting.
b. Use document.activeElement.blur() the activeElement returns still not the whole element.
Any suggestions? If lose focus is not feasible, is there a way to force focus on current tab?
Thanks

Can't fully reset activeElement (focus for the Tab key) to its default position

OK, I'm trying to reset the activeElement from the middle of the page so that the tab key would start from the top like, the same way as the page is just refreshed.
For that purpose (tested in FF and Chrome) I'm trying to use document.activeElement.blur() (from the browser console). As result, the selection of the <a href></a> gets visually removed (nice).
Also,running
document.activeElement after running document.activeElement.blur()
from console shows
<body class="ng-tns-0-0">
which looks good (the activeElement is body now?)
However, if I close the console and hit the Tab key, the focus appears on the next to the previous a href - Not to the link that is focused on page load + Tab key.
Why and how to fix that behavior?
The question appeared from the accessibility point of view, as the significant part of the page gets rendered with another content. The tab key needed to start over, like for a new page.
In fact, you shouldn't use blur() ever, and this method shouldn't even exist.
After having called blur(), you have no control of where the focus goes. It may go in menu bar, toolbars, or even go totally outside of the browser and/or become completely unrecoverable without a mouse.
The behavior you observe with firefox and chrome isn't standard, isn't specified anywhere, may depend on OS and/or browser settings, and you don't have control at all on it
The safest solution if you want to go back to the first element of the page is probably to focus that first element, rather than calling blur() and hope for the best.
In order for any application or website to be keyboard accessible, the focus must always be under control, i.e. you must always know exactly where it is. As the method blur() doesn't specify where the focus goes next, you lose control of the focus when using it; so you should never use it. As far as I know, it has probably no legitimate use.

Why IE10 fires beforeunload event when clicking on anchor element with javascript href and how to prevent it

In order to track when user leaves the page, we listen to beforeunload event. Everything works fine until user, that uses IE10, clicks on empty link (anchor) with javascript in href parameter instead of url. For example:
Empty link with JS in href
This case makes IE10 sometimes fire beforeunload event. Chrome/IE11 work fine (0 beforeunloads), while IE10 fires it from time to time, especially if you click it fast. Here is JSFiddle to try it.
Does anyone know why does it happen and how to fix it? I would be happy to remove/replace such anchors in mark-up, but it is impossible in my case.
Thanks.
Technically, IE10 may be considered correct to do so because you are unloading the page... kind of. If your link were:
<a href="javascript:'blah';">
Then you would end up on a new page with just the content 'blah'. This is how javascript: links work. void returns nothing (undefined), and when a javascript: link returns nothing then it does not replace the page contents.
A similar thing would happen, in theory, if the target resource is a download - the page would normally be unloaded but because the target is a download, the page does not change. And HTTP response of 204 No Content should also trigger this behaviour.
However, as you have noticed, this is undesirable behaviour and so it has become more common to see that the browser will not trigger an unload event until the page itself really is being unloaded. Unfortunately, this is a browser-level thing and outside your control, as far as I'm aware.
To my knowledge the only real fix for this would be to ensure you are properly preventDefaulting your click event.

Google Chrome duplicates JavaScript 'focus' event

I've noticed a strange issue with how Chrome handles javascript focus event. The fact is, it continuosly triggers focus event, even if it occurs only once. I've made a bit of research here and found questions where people run into the same issue when using alert(). When they close the alert window, the focus returns to their inputs and a handler triggers again and again. In my case, the problem is different, as I am using console.log(), and from time to time I get the same log 2 or even 3 times. I've noticed it usually happens when I clear the console, and then focus on an element. When I try to repeat it, it does not occur any more.
The scenario:
Clear console
Focus on element (2 or 3 console messages)
Focus on other identical element or unfocus and focus again on the
same one (no problems)
Clear console
Focus on element (2 or 3 console messages - the problem is back!)
I've created a jsfiddle, please check it out:
http://jsfiddle.net/ffuWT/3/
The question is, what is the reason for this issue and how can I work around it?
Creepy how these things can happen. I've run into this exact issue at work today, but have quickly written this off suspecting dodgy event listening and propagation in a 3rd-party plugin (jQuery customInput). I'll double-check your jsfiddle tomorrow.
I'm unable to recreate your exact output on my currently available setup (Chrome v17 on a Mac) but I do have a theory to share. In your scenario and in Ben Lee's comment the consistent part is shifting focus to another window (console in your case).
Check out http://www.quirksmode.org/dom/events/blurfocus.html under "Window + focusable element":
If the window is sent backward while a focusable element is focused,
blur events should fire on both. If the window is brought forward
again, focus events should fire on both.
And next, in the compatibility table it's noted that
Safari Windows fires two focus events.
Maybe Chrome finally got this "feature" too, coming from the Webkit family and all?
I was able to recreate the problem (using your jsFiddle) and from what I can see it only occurs when you click the select without having focus on/in the result frame.
Click within the frame but not on the selects before you click to expand one of the selects and you´ll only see one line logged.
You can also append /show to the jsFiddle URL to view the result in a separate window.
It seems like focusing the window by clicking on a select control triggers the event multiple times.
Open this demo and unfocus the browser window (by clicking the desktop, taskbar or another window) and then click on one of the selects to expand its options and view the console.
Using Chrome 17.0.963.79 m.

Detects a click outside document

I am having a problem to detect a click event outside document, for instance in the closing button of the browser without using the onbeforeunload event, because I have a JSP page that is processing something, using meta refresh to give the status of the process evolution.
Since I am using meta refresh I cannot use window.onbeforeunload event to prevent/confirm the user to exit because the meta refresh will fire up the event. Thus, I need to check manually if the mouse will be clicked outside my document.
I can check if the mouse coordinates are outside, thus can´t associate an click event to that in IE8.
if (window.event.clientY < 82 && window.onclick)
Someone have any idea out achieve this issue?
Thanks in advance!
Detecting the close button isn't possible but you can detect if the user is losing focus of the browser by doing:
$(window).blur(function() {
alert('lost focus');
}
It's not possible. Events don't fire outside of the document, including clicks on the window chrome.
I think you will need to think about what you're trying to achieve. It sounds like a shaky design if you must get the close event of the page. Lots of other events will affect you if that is of a concern.
If you have a JSP page producing and showing the status by a meta refresh - what is your problem with the window closing? That should be of your concern, not how to detect a browser close event.

Categories

Resources