假设我在一个HTML输入框上附加了一个模糊函数,如下所示:
<input id="myInput" onblur="function() { ... }"></input>
是否有一种方法来获得导致模糊事件的元素的ID(被点击的元素)在函数内?如何?
例如,假设我有这样一个张成的空间:
<span id="mySpan">Hello World</span>
如果我在输入元素有焦点之后点击span,输入元素将失去它的焦点。该函数如何知道被单击的是mySpan ?
PS:如果跨度的onclick事件发生在输入元素的onblur事件之前,我的问题就解决了,因为我可以设置一些状态值,指示特定的元素已被单击。
PPS:这个问题的背景是,我想从外部触发一个AJAX自动补全控件(从一个可点击的元素)来显示它的建议,而不会因为输入元素上的模糊事件而立即消失建议。因此,我想检查是否有一个特定的元素被单击了模糊函数,如果是这样,忽略模糊事件。
嗯…在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" />
注意:这个技巧不适用于由键盘tab键引起的焦点变化,在Chrome和Safari中也完全不起作用。使用activeElement (IE除外)的一个大问题是,在处理模糊事件之前,它不会持续更新,并且在处理过程中可能根本没有有效值!这可以通过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>
然后在你的span的onClick中,用两个对象调用function():
<span id="mySpan" onClick="function(lastBlurred, this);">Hello World</span>
然后,函数可以决定是否触发Ajax。自动完成控件。该函数有点击对象和模糊对象。onBlur已经发生了,所以它不会让建议消失。
我也试图使自动补全器忽略模糊,如果一个特定的元素点击,并有一个工作的解决方案,但只有Firefox由于显式originaltarget
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);
}
}
}
);
This code wraps default onBlur method of Autocompleter and checks if ignoreBlurEventElement parameters is set. if it is set, it checks everytime to see if clicked element is ignoreBlurEventElement or not. If it is, Autocompleter does not cal onBlur, else it calls onBlur. The only problem with this is that it only works in Firefox because explicitOriginalTarget property is Mozilla specific . Now I am trying to find a different way than using explicitOriginalTarget. The solution you have mentioned requires you to add onclick behaviour manually to the element. If I can't manage to solve explicitOriginalTarget issue, I guess I will follow your solution.
可以这样说:
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>
2015答案:根据UI Events,你可以使用事件的relatedTarget属性:
用于标识与焦点相关的次要EventTarget
事件,这取决于事件的类型。
对于模糊事件,
relatedTarget:事件目标接收焦点。
例子:
函数blurListener(事件){
event.target.className = '模糊';
如果(event.relatedTarget)
event.relatedTarget.className = 'focused';
}
[].forEach.call(document.querySelectorAll('input'), function(el) {
埃尔。addEventListener('blur', blurListener, false);
});
.模糊{背景:橙色}
.集中{背景:lime}
<p>模糊的元素将变成橙色
<p>聚焦的元素应该变成石灰
<input /><input /><input />
注意Firefox直到48版才支持relatedTarget (bug 962251, MDN)。
我写了一个替代方案如何使任何元素可聚焦和“模糊”。
它基于将一个元素设置为contentteditable,并在视觉上隐藏它,并禁用编辑模式本身:
el.addEventListener("keydown", function(e) {
e.preventDefault();
e.stopPropagation();
});
el.addEventListener("blur", cbBlur);
el.contentEditable = true;
DEMO
注:在Chrome, Firefox和Safari (OS X)中测试,对IE不确定。
相关:我正在寻找Vue的解决方案,所以对于那些感兴趣/好奇如何使用Vue Focusable指令实现这样的功能的人,请看看。