当发生"模糊"事件时,我如何找出哪个元素焦点去了*?

时间:2020-03-06 14:36:12  来源:igfitidea点击:

假设我将一个blur函数添加到HTML输入框中,如下所示:

<input id="myInput" onblur="function() { ... }"></input>

有没有一种方法可以获取导致函数内部触发" blur"事件(单击的元素)的元素的ID?如何?

例如,假设我的跨度是这样的:

<span id="mySpan">Hello World</span>

如果在输入元素具有焦点之后立即单击跨度,则输入元素将失去其焦点。函数如何知道单击的是" mySpan"?

PS:如果跨度的onclick事件发生在输入元素的onblur事件之前,那么我的问题将得到解决,因为我可以设置一些状态值来指示已单击特定元素。

PPS:此问题的背景是,我想从外部(从可单击元素)触发AJAX自动完成器控件以显示其建议,而这些建议不会由于输入元素上的blur事件而立即消失。因此,我想检查blur函数是否单击了一个特定元素,如果已单击,则忽略模糊事件。

解决方案

编辑:
一种不明智的做法是创建一个变量,以跟踪我们关心的每个元素的焦点。因此,如果我们关心'myInput'失去了焦点,请为其设置一个变量以使其成为焦点。

<script type="text/javascript">
   var lastFocusedElement;
</script>
<input id="myInput" onFocus="lastFocusedElement=this;" />

原始答案:
我们可以将" this"传递给函数。

<input id="myInput" onblur="function(this){
   var theId = this.id; // will be 'myInput'
}" />

这条路:

<script type="text/javascript">
    function yourFunction(element) {
        alert(element);
    }
</script>
<input id="myinput" onblur="yourFunction(this)">

或者,如果我们通过JavaScript(在此示例中为jQuery)添加了侦听器,则:

var input = $('#myinput').blur(function() {
    alert(this);
});

编辑:对不起。我看错了问题。

我认为这不是可能的,
使用IE时,我们可以尝试使用window.event.toElement,但不适用于Firefox!

嗯...在Firefox中,我们可以使用explicitOriginalTarget来拉动被单击的元素。我希望toElement对IE也能做到这一点,但似乎不起作用...但是,我们可以从文档中拉出新聚焦的元素:

function showBlur(ev)
{
   var target = ev.explicitOriginalTarget||document.activeElement;
   document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
}

...

<button id="btn1" onblur="showBlur(event)">Button 1</button>
<button id="btn2" onblur="showBlur(event)">Button 2</button>
<button id="btn3" onblur="showBlur(event)">Button 3</button>
<input id="focused" type="text" disabled="disabled" />

警告:此技术不适用于使用键盘在字段之间切换引起的焦点更改,并且根本不适用于Chrome或者Safari。使用activeElement(IE除外)的最大问题是,直到处理完blur事件之后,它才会持续更新,并且在处理过程中可能根本没有有效值!可以通过更改Michiel最终使用的技术来缓解这种情况:

function showBlur(ev)
{
  // Use timeout to delay examination of activeElement until after blur/focus 
  // events have been processed.
  setTimeout(function()
  {
    var target = document.activeElement;
    document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
  }, 1);
}

这应该在大多数现代浏览器(在Chrome,IE和Firefox中测试)上都可以使用,但要注意的是,Chrome不会将重点放在单击的按钮上(相对于选项卡式)。

我们可以在何时以及何时撤销我们正在检查的内容吗?那就是如果我们想起最后模糊的东西:

<input id="myInput" onblur="lastBlurred=this;"></input>

然后在跨度的onClick中,对两个对象调用function():

<span id="mySpan" onClick="function(lastBlurred, this);">Hello World</span>

然后,函数可以决定是否触发Ajax.AutoCompleter控件。该函数具有单击的对象和模糊的对象。 onBlur已经发生,因此不会使建议消失。

我建议使用全局变量blurfrom和blurto。然后,配置所有我们要关注的元素,以在它们失去焦点时将它们在DOM中的位置分配给变量blurfrom。另外,配置它们,以便获得焦点将变量blurto设置为它们在DOM中的位置。然后,我们可以一起使用另一个功能来分析模糊和模糊数据。

我最终通过onblur事件超时解决了它(由于不是StackOverflow的朋友的建议):

<input id="myInput" onblur="setTimeout(function() {alert(clickSrc);},200);"></input>
<span onclick="clickSrc='mySpan';" id="mySpan">Hello World</span>

在FF和IE中均可使用。

我还试图使Autocompleter在单击特定元素并具有有效解决方案时忽略模糊,但仅适用于Firefox,因为explicitOriginalTarget

Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap( 
        function(origfunc, ev) {
            if ($(this.options.ignoreBlurEventElement)) {
                var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode : ev.explicitOriginalTarget);
                if (!newTargetElement.descendantOf($(this.options.ignoreBlurEventElement))) {
                    return origfunc(ev);
                }
            }
        }
    );

这段代码包装了Autocompleter的默认onBlur方法,并检查是否设置了ignoreBlurEventElement参数。如果已设置,它将每次检查以查看单击的元素是否为ignoreBlurEventElement。如果是这样,则自动完成程序将不会校准onBlur,否则它将调用onBlur。唯一的问题是它仅在Firefox中可用,因为explicitOriginalTarget属性是Mozilla特定的。现在,我试图找到一种不同于使用explicitOriginalTarget的方法。我们提到的解决方案要求我们手动将onclick行为添加到元素。如果我无法解决explicitOriginalTarget问题,我想我会遵循解决方案。

请记住,使用explicitOriginalTarget的解决方案不适用于从文本输入到文本输入的跳转。

尝试用以下文本输入替换按钮,我们将看到区别:

<input id="btn1" onblur="showBlur(event)" value="text1">
<input id="btn2" onblur="showBlur(event)" value="text2">
<input id="btn3" onblur="showBlur(event)" value="text3">

可以使用文档的mousedown事件代替模糊事件:

$(document).mousedown(function(){
  if ($(event.target).attr("id") == "mySpan") {
    // some process
  }
});