如何检测div何时失去焦点?

鉴于以下标记,我想检测编辑器何时失去焦点:

编辑:当用户通过输入元素进行选项卡时,每个编辑器div失去焦点(意味着它们在div外面标记)将加载类添加到失去焦点的div。

这个jquery是我期望的工作,但它没有做任何事情:

 $(".editor") .blur(function(){ $(this).addClass("loading"); }); 

这似乎有效,直到您添加控制台日志并意识到它正在触发输入的每个焦点。

 $('div.editor input').focus( function() { $(this).parent() .addClass("focused") .focusout(function() { console.log('focusout'); $(this).removeClass("focused") .addClass("loading"); }); }); 

这是我一直在研究的测试用例的jsfiddle 。 我知道我在这里缺少一些基本的东西。 有人能开导我吗?

编辑:在下面的一些评论之后,我几乎按照我想要的方式工作。 现在的问题是检测焦点何时改变到编辑器div之外的某个地方。 这是我目前的实施:

 function loadData() { console.log('loading data for editor ' + $(this).attr('id')); var $editor = $(this).removeClass('loaded') .addClass('loading'); $.post('/echo/json/', { delay: 2 }) .done(function () { $editor.removeClass('loading') .addClass('loaded'); }); } $('div.editor input').on('focusin', function () { console.log('focus changed'); $editor = $(this).closest('.editor'); console.log('current editor is ' + $editor.attr('id')); if (!$editor.hasClass('focused')) { console.log('switched editors'); $('.editor.focused') .removeClass('focused') .each(loadData); $editor.addClass('focused'); } }) 

有点复杂,并使用类的状态。 我还添加了下一个复杂性,即在编辑器失去焦点时进行异步调用。 这是我当前工作的一个问题。

如果您希望将输入对的输入和退出视为组合成单个控件,则需要查看获得焦点的元素是否在同一editor 。 你可以这样做,使用setTimeout为0延迟一个周期的检查(等待所有当前任务完成)。

 $('div.editor input').focusout(function () { var $editor = $(this).closest('.editor'); // wait for the new element to be focused setTimeout(function () { // See if the new focused element is in the editor if ($.contains($editor[0], document.activeElement)) { $editor.addClass("focused").removeClass("loading"); } else { $editor.removeClass("focused").addClass("loading"); } }, 1); }); 

JSFiddle: http : //jsfiddle.net/TrueBlueAussie/8s8ayv52/18/

要完成拼图(获得初始绿色状态),您还需要捕获focusin事件并查看它是否来自同一编辑器(将以前的焦点元素保存在全局等)。

旁注:我最近不得不编写一个jQuery插件,它为元素组完成了所有这些操作。 它生成自定义groupfocusgroupblur事件,以使其余代码更易于使用。

更新1: http : //jsfiddle.net/TrueBlueAussie/0y2dvxpf/4/

根据您的新示例,您可以反复捕捉焦点而不会造成伤害,因此无需追踪之前的焦点。 使用我之前的setTimeout示例解决了在div外部单击时遇到的问题。

 $('div.editor input').focusin(function(){ var $editor = $(this).closest('.editor'); $editor.addClass("focused").removeClass("loading"); }).focusout(function () { var $editor = $(this).closest('.editor'); // wait for the new element to be focused setTimeout(function () { // See if the new focused element is in the editor if (!$.contains($editor[0], document.activeElement)) { $editor.removeClass("focused").each(loadData); } }, 0); }); 

这对我有用:

 $(".editor").on("focusout", function() { var $this = $(this); setTimeout(function() { $this.toggleClass("loading", !($this.find(":focus").length)); }, 0); }); 

例:

http://jsfiddle.net/Meligy/Lxm6720k/

我想你可以做到这一点。 这是我做过的一个例子。 看看: http : //jsfiddle.net/igoralves1/j9soL21x/

 $( "#divTest" ).focusout(function() { alert("focusout"); });