216

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

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

有没有办法blur在函数内部获取导致事件触发的元素的 ID(被点击的元素)?如何?

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

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

如果我在输入元素获得焦点后立即单击跨度,则输入元素将失去焦点。该函数如何知道它是mySpan被点击的?

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

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

4

23 回答 23

96

2015回答:根据UI Events,您可以使用relatedTarget事件的属性:

用于识别EventTarget与焦点事件相关的次要事件,具体取决于事件的类型。

对于blur活动,

relatedTarget:事件目标接收焦点。

例子:

function blurListener(event) {
  event.target.className = 'blurred';
  if(event.relatedTarget)
    event.relatedTarget.className = 'focused';
}
[].forEach.call(document.querySelectorAll('input'), function(el) {
  el.addEventListener('blur', blurListener, false);
});
.blurred { background: orange }
.focused { background: lime }
<p>Blurred elements will become orange.</p>
<p>Focused elements should become lime.</p>
<input /><input /><input />

注意 FirefoxrelatedTarget直到版本 48(错误 962251MDN)才支持。

于 2015-10-25T03:42:30.297 回答
94

嗯... 在 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 不会将焦点放在被点击的按钮上(与标签页相比)。

于 2008-09-23T15:25:04.660 回答
20

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

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

适用于 FF 和 IE。

于 2008-09-24T17:17:36.097 回答
17

可以使用文档的 mousedown 事件而不是模糊:

$(document).mousedown(function(){
  if ($(event.target).attr("id") == "mySpan") {
    // some process
  }
});
于 2010-04-03T19:49:13.390 回答
10

type 的实例FocusEvent具有relatedTarget属性,但是,直到 FF 的版本 47,具体而言,此属性返回null,从 48 开始它已经工作。

你可以在这里看到更多。

于 2016-12-02T05:05:34.273 回答
3

适用于 Google Chrome v66.x、Mozilla v59.x 和 Microsoft Edge... 使用 jQuery 的解决方案。

我在 Internet Explorer 9 中测试但不支持。

$("#YourElement").blur(function(e){
     var InputTarget =  $(e.relatedTarget).attr("id"); // GET ID Element
     console.log(InputTarget);
     if(target == "YourId") { // If you want validate or make a action to specfic element
          ... // your code
     }
});

在其他 Internet Explorer 版本中评论您的测试。

于 2018-05-15T00:16:51.273 回答
2

你能扭转你正在检查的内容和时间吗?也就是说,如果您还记得最后模糊的内容:

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

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

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

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

于 2008-09-23T23:36:32.450 回答
2

如果单击特定元素并有一个有效的解决方案,我还试图让 Autocompleter 忽略模糊,但由于 explicitOriginalTarget 仅适用于 Firefox

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。如果是,Autocompleter 不会调用 onBlur,否则它会调用 onBlur。唯一的问题是它只适用于 Firefox,因为 explicitOriginalTarget 属性是 Mozilla 特定的。现在我试图找到一种不同于使用explicitOriginalTarget 的方法。您提到的解决方案要求您手动将 onclick 行为添加到元素。如果我无法解决explicitOriginalTarget 问题,我想我会遵循您的解决方案。

于 2008-10-07T10:56:06.427 回答
1

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

于 2008-09-23T15:01:49.223 回答
1

使用这样的东西:

var myVar = null;

然后在你的函数里面:

myVar = fldID;

进而:

setTimeout(setFocus,1000)

进而:

function setFocus(){ document.getElementById(fldID).focus(); }

最终代码:

<html>
<head>
    <script type="text/javascript">
        function somefunction(){
            var myVar = null;

            myVar = document.getElementById('myInput');

            if(myVar.value=='')
                setTimeout(setFocusOnJobTitle,1000);
            else
                myVar.value='Success';
        }
        function setFocusOnJobTitle(){
            document.getElementById('myInput').focus();
        }
    </script>
</head>
<body>
<label id="jobTitleId" for="myInput">Job Title</label>
<input id="myInput" onblur="somefunction();"></input>
</body>
</html>
于 2012-01-13T15:45:07.277 回答
1

您可以使用以下方法修复 IE:

 event.currentTarget.firstChild.ownerDocument.activeElement

它看起来像 FF 的“explicitOriginalTarget”。

安托万和 J

于 2016-06-29T13:26:40.750 回答
1

this answer中所述,您可以检查 的值document.activeElementdocument是一个全局变量,所以你不必做任何魔法就可以在你的 onBlur 处理程序中使用它:

function myOnBlur(e) {
  if(document.activeElement ===
       document.getElementById('elementToCheckForFocus')) {
    // Focus went where we expected!
    // ...
  }
}
于 2016-11-30T22:05:45.613 回答
1
  • document.activeElement 可能是父节点(例如 body 节点,因为它处于从目标切换到另一个目标的临时阶段),因此它不适用于您的范围
  • ev.explicitOriginalTarget 并不总是被重视

所以最好的方法是使用 onclick 对 body 事件间接理解你的 node(event.target) 是模糊的

于 2017-05-06T19:57:08.310 回答
0

编辑: 一个hacky方法是创建一个变量来跟踪您关心的每个元素的焦点。因此,如果您关心“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'
}" />
于 2008-09-23T14:51:01.060 回答
0

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

于 2008-09-23T23:40:42.283 回答
0

请记住,使用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">
于 2009-06-03T22:06:35.407 回答
0

我一直在使用相同的功能,发现 FF、IE、Chrome 和 Opera 能够提供事件的源元素。我没有测试过 Safari,但我猜它可能有类似的东西。

$('#Form').keyup(function (e) {
    var ctrl = null;
    if (e.originalEvent.explicitOriginalTarget) { // FF
        ctrl = e.originalEvent.explicitOriginalTarget;
    }
    else if (e.originalEvent.srcElement) { // IE, Chrome and Opera
        ctrl = e.originalEvent.srcElement;
    }
    //...
});
于 2011-06-01T14:32:06.543 回答
0

我不喜欢在编写 javascript 时使用超时,所以我会以 Michiel Borkent 的相反方式来做。(没有尝试后面的代码,但你应该明白)。

<input id="myInput" onblur="blured = this.id;"></input>
<span onfocus = "sortOfCallback(this.id)" id="mySpan">Hello World</span>

在头上是这样的

<head>
    <script type="text/javascript">
        function sortOfCallback(id){
            bluredElement = document.getElementById(blured);
            // Do whatever you want on the blured element with the id of the focus element


        }

    </script>
</head>
于 2012-03-29T15:37:56.013 回答
0

我写了一个替代解决方案,如何使任何元素可聚焦和“模糊”。

它基于将元素制作为contentEditable并在视觉上隐藏它并禁用编辑模式本身:

el.addEventListener("keydown", function(e) {
  e.preventDefault();
  e.stopPropagation();
});

el.addEventListener("blur", cbBlur);
el.contentEditable = true;

演示

注意:在 Chrome、Firefox 和 Safari (OS X) 中测试。不确定IE。


相关:我正在寻找 VueJs 的解决方案,所以对于那些对如何使用 Vue Focusable 指令实现此类功能感兴趣/好奇的人,请看一下

于 2017-03-24T22:41:04.580 回答
-2

我在答案中只看到黑客,但实际上有一个非常易于使用的内置解决方案:基本上你可以像这样捕获焦点元素:

const focusedElement = document.activeElement

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

于 2017-08-28T14:11:00.420 回答
-3

这边走:

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

编辑:对不起。我误读了这个问题。

于 2008-09-23T14:51:52.523 回答
-3


我认为它很容易通过 jquery 通过传递导致“this”中的 onblur 事件的字段的引用来实现。
例如

<input type="text" id="text1" onblur="showMessageOnOnblur(this)">

function showMessageOnOnblur(field){
    alert($(field).attr("id"));
}

谢谢
莫妮卡

于 2012-08-17T11:15:52.350 回答
-3

你可以这样:

<script type="text/javascript">
function myFunction(thisElement) 
{
    document.getElementByName(thisElement)[0];
}
</script>
<input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>
于 2015-04-17T16:10:01.717 回答