How to remove focus from activeElement when changing tabs (onfocus/onblur)? - javascript

I'm trying to remove focus from a (jQuery Mobile) text input when a user switches tabs on desktop. While I can correctly identify the activeElement in the below console, I cannot edit any of its properties or remove its focus.
This is what I'm doing:
// inside some init method
window.onfocus = function () {
// triggers
console.log(document.activeElement);
if (document.activeElement.tagName !== "BODY") {
console.log("clear focus");
document.activeElement.blur();
document.activeElement.className = "FOOBAR";
}
};
When I'm on a form and focus a text input, then switch to another tab and go back to the tab with the form, the event listener triggers and my still active input is correctly logged. However that's it... I can't blur or edit any of the elements properties.
Question:
How do I correctly remove focus from the active element either on window.onfocus or window.onblur?
Thanks!
PS: it also does not work with jQuery:
$(window).on("focus", function () {
$(document.activeElement).blur();
});
and I'm looking for a JavaScript only solution.
EDIT:
document.activeElement.blur() works fine from the console, but not from my listener.

Ok. This works:
window.onblur = function () {
document.activeElement.blur();
};
So it seemed the blur worked fine, because if I console activeElemnt before and after my call to blur() it switched from an INPUT to the BODY tag. Correctly, my body has it's class set to FOOBAR. Problem for me was that the text element still retained focus, but I assume this is due to some handler inside jQuery Mobile.
The above solution works the other way around. I remove focus of the activeElement when the user switches a tab. Works.

Related

Input focus and blur firing when window gets focus

I have a text input on a page to which I have bound focus() and blur() events. I'm having an issue where focus and then blur are firing unexpectedly if I follow the these steps:
Click on input, focus() fires. OK.
Click out of window on another window, blur() fires. OK.
Click back on original window, focus() and then blur() on the input both fire. PROBLEM!
$('#password').focus(function(){
$('#passwordStrength').slideDown(500);
}).blur(function(){
$('#passwordStrength').slideUp(500);
});
I really need the focus() and blur() events not to fire when the window regains focus as it causes a div to quickly appear and then disappear.
Any ideas on how to stop this?
I ended up getting around this by checking if the document has focus as part of my blur function.
$('#password').focus(function(){
$('#passwordStrength').slideDown(500);
}).blur(function(){
if (document.hasFocus()) {
$('#passwordStrength').slideUp(500);
}
});
This means that my strength box stays on the page when clicking away and then behaves appropriately when clicking back into the window.
Thanks to the commenters for trying to help and sending me on the right path.
You can use window.onfocus to detect if the current tab is focused.
function focus () {
$('#password').focus(function(){
$('#passwordStrength').slideDown(500);
}).blur(function(){
$('#passwordStrength').slideUp(500);
});
}
focus();
window.onfocus = function () {
$('#password').focus();
focus();
}
Here the fiddle

Remove BS4 jQuery document.focus event programmatically

I have a Bootstrap 4 text field that I cannot give focus to. I have tried:
Clicking in the field
Using jQuery focus in console
Tabbing to it
Assigning autofocus attribute
When I look in chrome devtools Elements > EventListeners tab, go down to focus and remove the focus EventListeners, the field can get focus again. Also if I remove focusin listener it works.
I have tried in the console:
jQuery .off on the document object
$(document).off( "focusin");
jQuery .off on the window object
and
var customFunction = function (event) {
document.removeEventListener('focus',customFunction, false );
};
document.addEventListener("focus", customFunction, false);
Live Page
Here is what I mean about the devtools event listener screen
DevTools Screenshot with Annotation
Not really sure what to do next.
Thanks in advance.
This fixed the issue by removing jQuery's document.focus() EventListener which was blocking the input for some reason.
$btnSignContracts.on('click', function(e) {
$(document).off("focusin");
$(document).off("focus");
});
The field is working properly now.

Why does modal pop up pressing space bar press? How do I prevent it?

I have an action planned on a space bar click. It does happen.
// when space bar is pressed
do-something; // Applied on the $(document).keypress..
But, when I press space bar, along with the event/action that has to be triggered, modal load/shows up again. Why is it so? I have tried to prevent modal from loading again :
$('#goal').on('hidden.bs.modal',function() {
$(document).focus(); // Get the button that triggered modal
// out of focus
});
But the document, doesn't get focus and the button that triggered modal-load remains in focus until I click on the screen to bring the document back to focus. How could I prevent modal from loading again on space bar press?
I also tried the blur() function on button that triggers modal. But it doesn't help?
Using $(document).focus(); will have no effect, because document is not a focusable element, it's actually not an element at all. Try using document.activeElement to get the active element and blur it.
document.activeElement.blur();
To do this, you will need to listen for the event when the modal is closed, hidden.bs.modal, since Bootstrap will automatically return the focus to the button on close.
Example (Live):
$(document).on('hidden.bs.modal', function() {
document.activeElement.blur();
});
Alternately, you could set the focus to a focusable element in the model itself if one exists. This would probably give the most-pleasant user experience.
It might be due to default focus on an element which might be causing this. Tried event.preventDefault(); ?
// when space bar is pressed
event.preventDefault();
do-something; // Applied on the $(document).keypress..
This is a bit hard to answer without seeing more of your code or, even better, a jsfiddle that demonstrates your problem.
But in general, you can prevent the space bar keypress from having any side effects by returning false from the jquery event handler function to indicate that you've consumed the event.
So (guessing what your event handler looks like)
$('...').keypress( function(event) {
if ( event.which == 32 ) {
doSomething();
return false;
}
});
Hope this helps. If not, please give a bit more details.
You can avoid the button gaining focus this way:
$('#yourButtonId').focus(function(){
$(this).blur();
});
I tried this in the jsFiddle you posted and it works, the space bar doesn't open the modal anymore.

Why is there a delay when blurring in CKEDITOR and can I get around it?

I'm trying to add a class to my body tag when I focus on an input, textarea, or CKeditor instance. And remove the class when I blur from any of these. The problem is that when I blur from a CKeditor instance and immediately focus on an input or textarea, the focus event happens before the blur event does. There is a significant delay when blurring from a CKeditor instance. I've tried using delay() and setTimeout() in addition to many other things and I can't get it to work. Since it's blurring after I focus, the focus event is adding the class to the body and then the blur event is removing the class.
I'm doing this because I need to reposition the header and hide the footer when the user is on a mobile device the keyboard displays. Below is the code I current have. Does anyone have any ideas on how I can get around this? Thanks!
if ($("html").hasClass("touch")) {
// Set focus and blur listeners for all editors to be created.
CKEDITOR.on( 'instanceReady', function() {
var editor = txtEditor.get_instance();
editor.on('focus', function(e) {
$("body").addClass(fix);
});
editor.on('blur', function(e) {
$("body").removeClass(fix);
});
});
$("input").on("focus", function(e) {
$("body").addClass(fix);
})
.on("blur", function(e) {
$("body").removeClass(fix);
});
}
The delay is caused by the focus manager. It waits 200ms for the next editor UI component to receive focus. It has to do wait, because in various cases and depending on browsers focus may be moved from one component (e.g. editable element) to another component (toolbar, elements path, dialog) with a significant delay. I know from my own experience that it can even exceed 100ms. If it wasn't waiting the editor#blur and editor#focus events would be fired many times when working within editor.
In your case, the input element should behave like editor's UI component. If it gets focus the same should happen as when editor gets focus and vice versa. I think that the easiest solution is to register it as editor's UI component:
CKEDITOR.on('instanceReady', function() {
var editor = txtEditor.get_instance();
editor.focusManager.add(new CKEDITOR.dom.element(inputEl));
editor.on('focus', function(e) {
$("body").addClass(fix);
});
editor.on('blur', function(e) {
$("body").removeClass(fix);
});
});
Thanks for your feedback, but I got it. I was able to place an editor.focusManager.forceBlur() statement in the focus statement of my input fields. That way the blur from any previous ckeditors is immediate. Thanks again though!
Jesse

Does keypress() only fire when a textfield is focused in Firefox?

jQuery(document).ready(function ($) {
$('body').keypress(function (e) {
alert(e.which);
});
});
This will pop up an alert when a key is pressed in Chrome but not in Firefox. However, if I create a text field and focus it, then press a key, an alert will pop up in Firefox. (Even though $('body') is still the jQuery object.)
How can I get the event to fire in Firefox even when a textfield is not focused? Is there a workaround? I will be firing an event when the Enter key is pressed anywhere on the page.
Thanks guys
If you have no elements on the page, the browser might assume that the <body> element (or any of its descendants) doesn't have focus. Try binding your event to the document:
jQuery(document).ready(function ($) {
$(document).keypress(function (e) {
alert(e.which);
});
});
#DarthJDG is right, but you should still set focus on the window if you want to listen for keypresses immidiately after page load. in some cases browsers will leave focus on the address bar. so add:
$(window).focus();
after setting up the keypress handler

Categories

Resources