我正在尝试检测文本输入字段何时处于活动状态。我最初使用onfocu
实现,但是,当窗口不再是前景窗口时,会触发onblur
事件。这在我的申请中会产生意想不到的后果。标识为DOMActivate
的{{1}}事件,but in firefox this is NOT fired on text:input
fields。
文档中一次只能激活一个元素。一个活跃的 element不一定有焦点,但有焦点的元素是 始终是文档中的活动元素。例如,一个活跃的 窗口中不是前台窗口的元素没有 对焦。
开火:按钮,输入:按钮,输入:复选框,输入:文件,输入:图像,输入:密码,输入:收音机,输入:复位,输入:提交
不会触发:输入:text,select,textarea
我还使用input
事件进行了测试。但是,只有在实际输入框中时才会触发此事件。对于我的应用程序,我需要捕获文本输入字段在键入的任何内容之前处于活动状态,并且当窗口不在前台时它无法更改状态。
我认为可能有一种方法可以使用变异观察器来执行此操作,然后检查该变异元素是否具有activeElement
,但这似乎需要更多开销。我不认为有一个lostActiveElement事件,所以这也会增加一些额外的跟踪。有更直接/有效的方法吗?
这是使用addon sdk的firefox附加组件。
答案 0 :(得分:1)
我使用如下突变显示器得到了可用的结果:
var activeInputObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(document.activeElement.tagName === "INPUT"){
// do stuff based on this being the active input
}else{
// the else event is being used like a lost focus event now
// however, it now makes it global as opposed to per input
}
});
});
var activeInputConfig = { attributes: true, childList: true, characterData: true, subtree: true }
var activeInputTarget = document.querySelector('body');
if(target != null){
activeInputObserver.observe(activeInputTarget, activeInputConfig);
}
我在身体上使用突变观察者并使用subtree: true
监视所有后代。这并不理想,因为现在只要元素变为活动状态,它就会运行我的所有逻辑,而不是仅在输入字段上运行。它需要制作一些变量并跟踪它而不是仅仅依赖于每个元素事件。无法通过这种方式检测到没有长寿的元素。这种作品,但并不是很理想。
我试图在每个输入字段上放置和变异观察者,但成为活动元素不会触发变异:
var activeInputObservers = [];
inputFields = document.querySelectorAll("input");
for each (var inputField in inputFields){
var activeInputConfig = { attributes: true, childList: true, characterData: true, subtree: true }
var activeInputTarget = inputField;
var thisObserver = new MutationObserver(function(mutations) {
activeInputObservers.push(thisObserver);
mutations.forEach(function(mutation) {
console.log("active element:" + JSON.stringify(document.activeElement) );
});
});
thisObserver.observe(activeInputTarget, activeInputConfig);
}
使用上面的代码,只需单击元素或选中它就不会触发可观察到的更改(在字段中输入)。
activeElement
是文档的属性,因此您需要监视文档的更改;再次,您仍然无法捕获特定元素中的事件和事件,因此您需要在每次活动元素更改时运行操作。看起来输入字段本身没有任何变化。
答案 1 :(得分:0)
根据@dandavis的一些建议并玩游戏,我发现当窗口不在焦点时document.activeElement
不会取消设置。如果我在输入字段blur
事件中设置条件,它将不会冒泡到窗口。我担心这会破坏窗口在页面处于背景时窗口接收模糊的其他脚本,但是,出于我的插件的目的,这可以防止模糊操作发生。
inputFields = document.querySelectorAll("input");
for each (var inputField in inputFields){
inputField.onfocus = function(){
//do something when the input field get's focus
}
inputField.onblur = function(e){
inputStillActive = false;
if(this === document.activeElement){ //this will be the input field element
inputStillActive = true;
return; //or do something else knowing that inputStillActive will be true
}
}
}
不应该提早回来,应该可以采取一些行动。如果你只做其他或不等于你应该能够考虑到#34;真的失去了焦点"而不是"仍然活跃,但窗口失去焦点"。
在我的情况下,如果我有一个活动的输入元素,我想捕获用于KeePass autotype的值,所以我将当前输入字段名称和id添加到窗口标题,所以简化版本是像这样的东西:
var activeInputAttributes = {};
inputFields = document.querySelectorAll("input");
for each (var inputField in inputFields){
inputField.onfocus = function(){
activeInputAttributes["name"] = this.getAttribute("name");
activeInputAttributes["id"] = this.getAttribute("id");
console.log(activeInputAttributes);
}
inputField.onblur = function(e){
inputStillActive = false;
if(this !== document.activeElement){
activeInputAttributes["name"] = null;
activeInputAttributes["id"] = null;
}
console.log(activeInputAttributes);
}
}
当我实际离开输入字段时,activeInputAttributes仅打印到null
,当我将窗口放在后台时,不为null,这意味着值仍然可用于自动类型。我认为这比我在原始答案中观察更为理想。