Javascript 当文本输入字段在FireFox中变为活动(非焦点)时激发的事件

Javascript 当文本输入字段在FireFox中变为活动(非焦点)时激发的事件,javascript,dom,firefox-addon-sdk,Javascript,Dom,Firefox Addon Sdk,我试图检测文本输入字段何时处于活动状态。我最初是使用onfocus实现的,但是,当窗口不再是前台窗口时,会触发onblur事件。这在我的应用程序中会产生意想不到的后果。有一个id是触发的domcactivate事件 文档中一次只能有一个元素处于活动状态。活跃的 元素不一定有焦点,但有焦点的元素是 始终是文档中的活动元素。例如,一个活动的 窗口中不是前景窗口的元素没有 专注 激发:按钮,输入:按钮,输入:复选框,输入:文件,输入:图像,输入:密码,输入:收音机,输入:重置,输入:提交 不触发:输入

我试图检测文本输入字段何时处于活动状态。我最初是使用
onfocu
s实现的,但是,当窗口不再是前台窗口时,会触发
onblur
事件。这在我的应用程序中会产生意想不到的后果。有一个id是触发的
domcactivate
事件

文档中一次只能有一个元素处于活动状态。活跃的 元素不一定有焦点,但有焦点的元素是 始终是文档中的活动元素。例如,一个活动的 窗口中不是前景窗口的元素没有 专注

激发:按钮,输入:按钮,输入:复选框,输入:文件,输入:图像,输入:密码,输入:收音机,输入:重置,输入:提交

不触发:输入:文本,选择,文本区域

我还使用该事件进行了测试。但是,仅当您实际在框中键入时才会触发此事件。对于我的应用程序,我需要捕获文本输入字段在键入任何内容之前处于活动状态的时间,以及窗口不在前台时无法更改状态的时间

我认为可能有一种方法可以通过一个变异观察者来实现这一点,然后检查变异元素是否有,但这似乎需要更多的开销。我不认为有lostActiveElement事件,所以这也会增加一些额外的跟踪。有没有更直接/有效的方法


这是一个使用插件sdk的firefox插件。

我通过使用mutationobsever获得了可用的结果,如下所示:

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);
}
我在身体上使用突变观察者,并使用
子树: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);     
}
在上面的代码中,只需单击元素或在元素中使用Tab键不会触发可观察到的更改(在字段中键入会触发)


activeElement
是文档的一个属性,所以您需要监视文档的更改;同样,您仍然无法捕获特定元素中的事件,因此每次活动元素更改时都需要运行操作。输入字段本身看起来没有任何变化。

根据@dandavis的一些建议,我发现
文档.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 
        }

    }

}
与其早早返回,不如采取一些行动。如果你只做其他的或不相等的事情,你应该能够考虑“真正失去焦点”而不是“仍然活跃,但是窗口失去了焦点”。 在我的例子中,如果有一个输入元素处于活动状态,我希望捕获用于的值,因此我将当前输入字段名称和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);

    }

}

当我实际离开输入字段时,ActiveInputAttribute仅打印为
null
,而当我将窗口置于后台时,ActiveInputAttribute不为null,这意味着这些值仍可用于自动键入。我认为这比我最初的回答中的观察更理想。

你需要倾听窗口的
模糊事件(或者知道窗口何时不再在前景中的任何事情)。此外,使用文本框的
焦点
模糊
处理逻辑应该可以为您提供所需的一切。例如,如果文本框聚焦,则窗口被发送到背景,窗口的
模糊
事件和文本框的
模糊
事件将触发。但是你会忽略它,因为窗口的
blur
事件发生了(这意味着文本框没有完全模糊)。听起来有可能,但我需要在项目失去“活动”时取消设置。我遵循逻辑,但它需要协调多个事件。对,所以只有当窗口没有模糊,但文本框已经模糊时,您才会取消设置。不幸的是,你是对的,我很确定这是唯一的方法,除非你在模糊事件的顶部点击观看
activeElement
:if(e.target!=this | | e.target!=document.activeElement){return;}@dandavis这并不能满足我的需要。当我在文本字段的模糊处理程序中运行此操作时,如果我将窗口移动到背景,它确实会阻止触发模糊事件,但当我单击其他位置时,模糊事件不会触发,-就像我只单击页面的背景,而我在字段内不再处于活动状态,它仍然会模糊。