JavaScript FocusOut - get an element that receives focus

When the FocusOut event is raised, how do you know which element receives focus ?

The correct way is to use the relatedTarget event property . However, this does not seem to work in all browsers:

  • in Google Chrome works
  • in Firefox and Internet Explorer, the object associated with it is null
  • in Safari, the relatedTarget property doesn't even exist

I found a workaround that only works in IE (using document.activeElement), but I'm wondering if there is a generic solution that has proven effective in all major browsers .

Although I can find similar questions and answers, I have not found a solution that really works in all browsers.

EDIT: The example below shows what I mean.

HTML:

<input id="text1" type="text" value="first" /> <input id="text2" type="text" value="second" /> 

Javascript / jQuery:

 $('#text1').focusout(function(e) { // At this point, I want to know which element is receiving the focus (ie text2) alert(e.relatedTarget); // works in Chrome alert(document.activeElement); // works in IE // both do not work in Firefox or Safari }); 
+6
source share
4 answers

I have a hypothesis and workaround for firefox. document.activeElement seems to work. Then the focus hits, so it is deleted. By the time the focus falls (or maybe immediately after it), the focused element will again be. But there is nothing concentrated between them, so not a single element is reported as active.

My workaround is stupid to hack setTimeout. setTimeout( function() {console.log(document.activeElement)}, 1); reliably receives the active element. Of course, I tested only one car and spent all 90 seconds, but this is the best I have found so far.

+2
source

I believe you are looking for document.activeElement .

Returns the current focused item, that is, the item that will receive keypress events if the user types. This attribute is read-only.

https://developer.mozilla.org/en-US/docs/Web/API/document.activeElement

0
source
 //attach a focus out handler $("#id").focusOut($El_FocusOut); //display the id of new element being focused onto function $El_FocusOut($eventArgs){ //firefox specific focusout active element logi var activeElement = $eventArgs.orginalEvent.explicitOriginalTarget; alert($(activeElement).attr("id")) } 
0
source

I ran into the same problem using the textEditor PrimeFaces element.

I am using the following HTML.

 <div contenteditable="true" class="div-focus"> <h:outputText styleClass="OutputField" value="#{oController.panelTpl.getComment()}" escape="false" /> </div> <div class="text-editor"> <p:textEditor value="#{oController.panelTpl.txtComment.text}" /> </div> 

TextArea is defined twice, so when the form is displayed, the user sees only the first <div> widget, without seeing a specific toolbar.

When the user clicks on the displayed text, the focusin () event hides the <div class = "div-focus"> and display the <p: ​​textEditor> widget contained in the <div class = "text-editor"> parent element.

For this, I defined the following javascript code

 function onLoadDialog() { jQuery(".text-editor").hide(); jQuery(".div-focus").focusin(function() { $(this).hide(); $(this).next(".text-editor").show(); $(this).next(".text-editor").focus(); }); jQuery(".text-editor").focusout(function(e) { if ($(e.relatedTarget).closest(".text-editor").size() == 0) { $(this).hide(); $(this).prev(".div-focus").show(); $(this).prev(".div-focus").text($(this).text()); } }); } 

The onLoadDialog () function is called when the page loads and is used to hide the <div class = "text-editor> element and certain focusin () and focusout () events.

Event focusin () hide the <div class = "div-focus"> element and display the <div class = "text-editor"> element. When the user clicks on the text in the <div class = "div-focus"> element, this element is hidden and the next hidden element is displayed. Text editor <div class => focus elements.

Event focusout () hide <div class = "text-editor"> element and display <div class = "div-focus"> element ... only when the element that receives focus is not defined in <div class = " text-editor "> element.

The problem with element.focusout () is that it runs every time an element is included in the main element, even if the element receiving focus is defined in one element.

When you enter the house, you can enter the garage or living room or kitchen. When you enter the living room (through the external door), you enter the building. But when you leave the living room to the kitchen, you stay at home! If you leave the living room to go to the garden, you will leave the house (building).

The focusin () function implements the same principle, but not focusout ()!

if ($ (e.relatedTarget) .closest (". text-editor"). size () == 0) the line used in the focusout () event fixes this small difference!

CAUTION: The solution is not perfect, because I have some small problems that need to be solved when copying text from the textEditor widget to the outputText widget without formatting!

0
source

All Articles