13

FocusOut事件被引发时,你怎么知道哪个元素获得了焦点

正确的方法似乎是使用事件的relatedTarget属性。但是,这似乎不适用于所有浏览器:

  • 在谷歌浏览器中,它可以工作
  • 在 Firefox 和 Internet Explorer 中,relatedTarget 为空
  • 在 Safari 中,relatedTarget 属性甚至不存在

我找到了一种仅适用于 IE 的解决方法(使用 document.activeElement),但我想知道是否没有一种通用解决方案已被证明适用于所有主要浏览器

虽然我可以找到类似的问题和答案,但我还没有找到任何真正适用于所有浏览器的解决方案。

编辑:下面的例子说明了我的意思。

代码:

document.getElementById('text1').addEventListener('focusout', function(e) {
  // At this point, I want to know which element is receiving the focus (i.e. text2)
  console.log(e.relatedTarget); // works in Chrome
  console.log(document.activeElement); // works in IE
  // both do not work in Firefox or Safari
});
<input id="text1" type="text" value="first" />
<input id="text2" type="text" value="second" />

4

4 回答 4

6

我对 Firefox 有一个假设和解决方法。document.activeElement 似乎有效。然后focusout命中,所以它被删除。当 focusin 命中时(或者可能紧随其后),将再次出现一个焦点元素。但是在 out 和 in 之间没有任何焦点,因此没有元素被报告为活动的。

我的解决方法是一个愚蠢的 setTimeout hack。 setTimeout( function() {console.log(document.activeElement)}, 1);可靠地让我成为一个活跃的元素。当然,我只在一台机器上进行了测试,并且花了 90 秒的时间,但这是迄今为止我发现的最好的。

于 2014-05-19T20:59:21.413 回答
0

我相信您正在寻找的是document.activeElement.

返回当前获得焦点的元素,即如果用户键入任何键,将获得击键事件的元素。该属性是只读的。

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

于 2014-04-05T10:42:48.123 回答
0
//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.originalEvent.explicitOriginalTarget;
    alert($(activeElement).attr("id"))
}
于 2015-09-02T20:47:52.567 回答
0

我使用 textEditor PrimeFaces 元素遇到了同样的问题。

我使用以下 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 定义了两次,因此当显示表单时,用户只能看到第一个 <div> 小部件,而不会看到特定的工具栏。

当用户点击显示的文本时,focusin() 事件隐藏 <div class="div-focus"> 元素并显示 <div class="text-editor"> 父元素中包含的 <p:textEditor> 小部件。

为此,我定义了以下 javascript 代码

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());
            }
        });            
    }

onLoadDialog 函数()在页面加载时被调用,用于隐藏 <div class="text-editor> 元素以及定义的 focusin() 和 focusout() 事件。

focusin() 事件隐藏 <div class="div-focus"> 元素并显示 <div class="text-editor"> 元素。当用户点击 <div class="div-focus"> 元素中的文本时,该元素被隐藏并显示以下隐藏元素。<div class="text-editor"> 元素获得焦点。

focusout() 事件隐藏 <div class="text-editor"> 元素并显示 <div class="div-focus"> 元素...仅当获得焦点的元素未在 <div class="text-编辑器">元素。

element.focusout() 的问题在于每次包含在主元素中的元素时都会触发它,即使获得焦点的元素是在同一个元素中定义的。

当您进入房屋时,您可以通过车库或客厅或厨房进入。当您进入客厅(通过外门)时,您就进入了大楼。但是当你离开客厅去厨房时,你就呆在家里了!!!如果你离开客厅去花园,你就离开了房子(建筑)。

focusin() 函数实现相同的原理,但不是 focusout() !

if ($(e.relatedTarget).closest(".text-editor").size() == 0) 在 focusout() 事件中使用的行纠正了这个小差异!

注意:该解决方案并不完美,因为在将文本从 textEditor 小部件复制到 outputText 小部件而不进行格式化时,我有一些小问题需要解决!

于 2017-07-11T09:53:39.223 回答