当发生“模糊”事件时,如何找出哪些元素焦点去*?

假设我将一个blur函数附加到HTMLinput框中,如下所示:

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

有没有一种方法来获取引起blur事件的元素的ID(被点击的元素)的函数内? 怎么样?

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

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

如果在input元素具有焦点后单击该跨度,input元素将失去焦点。 函数如何知道是mySpan被点击了?

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

PPS:这个问题的背景是,我想从外部触发一个AJAX自动完成控件(来自一个可点击的元素)来显示它的build议,而不会立即因为input元素上的blur事件而消失。 所以我想检查blur函数,如果一个特定的元素已被点击,如果是的话,忽略模糊事件。

嗯…在Firefox中,你可以使用explicitOriginalTarget来拉取被点击的元素。 我期望元素对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中testing),但是Chrome并没有把焦点放在点击button上 (关于标签)。

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

用于标识与Focus事件相关的辅助EventTarget ,具体取决于事件的types。

对于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 /> 

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

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

适用于FF和IE。

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

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

我也试图让Autocompleter忽略模糊,如果一个特定的元素点击,并有一个工作的解决scheme,但只为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。 如果是,Autocompleter不会调用onBlur,否则调用onBlur。 唯一的问题是,它只能在Firefox中使用,因为explicitOriginalTarget属性是Mozilla特有的。 现在我试图find一个不同于使用explicitOriginalTarget的方法。 您提到的解决scheme需要您手动添加onclick行为到元素。 如果我无法解决明确的原始目标问题,我想我会按照你的解决scheme。

你能扭转你正在检查什么时候? 那就是如果你记得上一次模糊的话:

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

然后在onClick的span上,调用两个对象的function():

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

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

使用这样的东西:

 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> 

我认为这不是possibe,IE浏览器可以尝试使用window.event.toElement ,但它不能与Firefox的工作!

正如在这个答案中指出的,你可以检查document.activeElement的值。 document是一个全局variables,所以你不必在你的onBlur处理函数中使用它。

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

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

FocusEvent实例具有relatedTarget属性,但是,直到FF的版本47,具体来说,此属性返回null,从48已经工作。

编辑:这样做的一个奇怪的方法是创build一个variables,跟踪你关心的每个元素的焦点。 所以,如果你关心'myInput'失去了焦点,那么在焦点上设置一个variables。

 <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' }" /> 

我build议使用全局variablesblurfrom和blurto。 然后,configuration你所关心的所有元素,将它们在DOM中的位置分配给失去焦点的variablesblurfrom。 此外,configuration它们以获得焦点将variablesblurto设置为它们在DOM中位置。 然后,您可以使用另一个函数来分析模糊和数据。

请记住,使用explicitOriginalTarget的解决scheme不适用于文本input到文本input跳转。

尝试用下面的文本inputreplacebutton,你会看到不同之处:

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

我一直在玩这个相同的function,发现FF,IE,Chrome和Opera有能力提供一个事件的源元素。 我没有testing过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; } //... }); 

编码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> 

你可以修复IE浏览器:

  event.currentTarget.firstChild.ownerDocument.activeElement 

它看起来像FF的“explicitOriginalTarget”。

安托万和J

我写了一个替代解决scheme,如何使任何元素可以聚焦和“蓝调”。

它基于将contentEditable制作为contentEditable并以可视方式隐藏它并禁用编辑模式本身:

 el.addEventListener("keydown", function(e) { e.preventDefault(); e.stopPropagation(); }); el.addEventListener("blur", cbBlur); el.contentEditable = true; 

DEMO

注意:在Chrome,Firefox和Safari(OS X)中进行testing。 不知道有关IE。


相关:我正在寻找VueJs的解决scheme,所以对于那些有兴趣/好奇的人来说,如何使用Vue Focusable指令来实现这样的function,请看看 。

  • document.activeElement可以是一个父节点,所以它可以用于你的范围
  • ev.explicitOriginalTarget并不总是被重视

所以最好的方法是使用onclick事件间接理解你的节点是否模糊

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

 const focusedElement = document.activeElement 

https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElem ENT

这条路:

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

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

我认为它很容易通过jquery通过引起onblur事件的字段的引用在“this”中。
例如

 <input type="text" id="text1" onblur="showMessageOnOnblur(this)"> function showMessageOnOnblur(field){ alert($(field).attr("id")); } 

谢谢
莫妮卡

你可以这样做:

 <script type="text/javascript"> function myFunction(thisElement) { document.getElementByName(thisElement)[0]; } </script> <input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>