当发生“模糊”事件时,如何找出哪些元素焦点去*?
假设我将一个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)"/>