关于javascript:使用jQuery测试输入是否具有焦点 javascriptjavascript-eventsjqueryjquery-on Using jQuery to test if an input has focus 在我正在构建的站点的首页上,几个使用CSS :hover伪类在鼠标悬停时添加边框。 其中一个包含一个 ,如果其中的输入具有焦点,则使用jQuery保持边界。 除了IE6在以外的任何元素上不支持:hover之外,这种方法非常有效。 所以,对于这个浏览器,我们只使用jQuery来模拟使用$(#element).hover()方法的CSS :hover。 唯一的问题是,现在jQuery处理形式focus()和hover(),当输入具有焦点然后用户移入和移出鼠标时,边框消失。 我以为我们可以使用某种条件来阻止这种行为。 例如,如果我们测试鼠标输出是否有任何输入有焦点,我们可以阻止边界消失。 AFAIK,jQuery中没有:focus选择器,所以我不确定如何实现这一点。 有任何想法吗? 相关讨论 你可以试着把它简化为所需要的几句话,以及我发生了什么? 我认为您需要考虑捕捉焦点和模糊事件(docs.jquery.com/Events/focus和docs.jquery.com/Events/blur) 我在相关问题上发布了答案"JavaScript(或jQuery)中是否有'焦点'?"。 我已经增强了[gnarf引用的cletus方法](#2684561)。 jQuery 1.6+ jQuery添加了一个:focus选择器,因此我们不再需要自己添加它。只需使用$("..").is(":focus") jQuery 1.5及以下版本 编辑:随着时代的变迁,我们找到了更好的方法来测试焦点,最受欢迎的是Ben Alman的这个要点: 123jQuery.expr[':'].focus = function( elem ) { return elem === document.activeElement && ( elem.type || elem.href ); }; 引自Mathias Bynens: Note that the (elem.type || elem.href) test was added to filter out false positives like body. This way, we make sure to filter out all elements except form controls and hyperlinks. 你正在定义一个新的选择器。请参阅插件/编写。然后你可以这样做: 123if ($("...").is(":focus")) { ... } 要么: 1$("input:focus").doStuff(); 任何jQuery 如果你只是想弄清楚哪个元素有焦点,你可以使用 1$(document.activeElement) 如果您不确定版本是否为1.6或更低版本,则可以添加:focus选择器(如果缺少该版本): 12345678(function ( $ ) { var filters = $.expr[":"]; if ( !filters.focus ) { filters.focus = function( elem ) { return elem === document.activeElement && ( elem.type || elem.href ); }; } })( jQuery ); 相关讨论 这可能会导致误报。有关更多信息,请参阅stackoverflow.com/questions/967096/(感谢Ben Alman和Diego Perini)。 @Mathias Bynens - 感谢您的更新(非常欢迎您编辑此社区维基回答顺便提一下!) 当你需要它同时使用1.5和1.6时怎么办?我不想覆盖jQuery自己的焦点选择器。像if (!jQuery.expr[':'].focus) { /* gist from Ben Alman */ }这样的东西? @betamos - 完全正确......我会在答案中加入一些内容来反映这一点。 这不适用于运行后添加到DOM的动态元素... @Alex - 请在jsFiddle上提供一个简化的测试用例来显示问题,因为据我所知,没有理由不应该对"动态"元素起作用。我称之为恶作剧...... 我可能是错的,但它不适合我,只是想分享......我将不得不做更多的测试,以确保它不仅仅是我.. 也可以避免像这样的选择器中的聚焦元素:$('[placeholder]:not(:focus)') 仅供参考,如果你正在使用业力,你需要在测试中首先将元素添加到身体。请参阅stackoverflow.com/questions/19994424/ CSS: 123.focus { border-color:red; } JQuery的: 123456789 $(document).ready(function() { $('input').blur(function() { $('input').removeClass("focus"); }) .focus(function() { $(this).addClass("focus") }); }); 这是一个比目前接受的答案更强大的答案: 123jQuery.expr[':'].focus = function(elem) { return elem === document.activeElement && (elem.type || elem.href); }; 请注意,添加了(elem.type || elem.href)测试以过滤掉像body这样的误报。这样,我们确保过滤掉除表单控件和超链接之外的所有元素。 (取自Ben Alman的这个要点。) 2015年4月更新 由于这个问题已经存在了一段时间,并且一些新的约定已经发挥作用,我觉得我应该提到.live方法已被折旧。 取而代之的是,现在已经引入了.on方法。 他们的文档在解释它是如何工作时非常有用; The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live(). 因此,为了使您能够定位"输入聚焦"事件,您可以在脚本中使用它。就像是: 123$('input').on("focus", function(){ //do some stuff }); 这非常强大,甚至允许您使用TAB键。 我不完全确定你所追求的是什么,但这听起来可以通过将输入元素(或div?)的状态存储为变量来实现: 12345678910111213141516171819202122$('div').each(function(){ var childInputHasFocus = false; $(this).hover(function(){ if (childInputHasFocus) { // do something } else { } }, function() { if (childInputHasFocus) { // do something } else { } }); $('input', this) .focus(function(){ childInputHasFocus = true; }) .blur(function(){ childInputHasFocus = false; }); }); 相关讨论 这就是我最后做的事情,但我使用了一个任意的CSS类而不是一个全局的javascript变量。 我使用了这个变种。不需要新的jQuery插件。这让我成为一个快乐的露营者! 如果有人关心现在有一个更好的方法来捕捉焦点,$(foo).focus(...) http://api.jquery.com/focus/ 相关讨论 问题不在于关注元素...... 使用类来标记元素状态的替代方法是内部数据存储功能。 P.S。:您可以使用data()功能存储布尔值和任何您想要的值。它不只是关于字符串:) 1234567$("...").mouseover(function () { // store state on element }).mouseout(function () { // remove stored state on element }); 然后,这只是访问元素状态的问题。 你有没有想过使用mouseOver和mouseOut来模拟这个。另请参阅mouseEnter和mouseLeave 相关讨论 这基本上就是我在使用jQuery的悬停。您提供两个功能,一个用于鼠标输入,另一个用于鼠标输出。 我有一个.live("焦点")事件设置为选择()(突出显示)文本输入的内容,以便用户在键入新值之前不必选择它。 $(formObj)。选择(); 由于不同浏览器之间的怪癖,选择有时会被导致它的点击所取代,并且它会在有利于将光标置于文本字段之后取消选择内容(在FF中工作大部分正常但在IE中失败) 我以为我可以通过稍微延迟选择来解决这个问题... 的setTimeout(函数(){$(formObj)。选择();},200); 这样工作正常并且选择会持续,但是出现了一个有趣的问题。如果您从一个字段标注到下一个字段,焦点将在选择发生之前切换到下一个字段。由于选择抢断焦点,焦点将返回并触发新的"焦点"事件。这最终导致了一系列输入选择在屏幕上跳舞。 一个可行的解决方案是在执行select()之前检查该字段是否仍然具有焦点,但如上所述,没有简单的方法可以检查......我最终只是放弃了整个自动亮点,而不是转向应该是什么单个jQuery select()调用一个包含子程序的庞大函数... 有一个插件可以检查元素是否聚焦:http://plugins.jquery.com/project/focused 12345$('input').each(function(){ if ($(this) == $.focused()) { $(this).addClass('focused'); } }) 相关讨论 为什么在使用核心jquery时使用插件? 你是对的。但是我在2年前并不知道这个问题的解决方案。 我最后要做的是创建一个名为.elementhasfocus的任意类,它在jQuery focus()函数中添加和删除。当hover()函数在鼠标输出时运行时,它会检查.elementhasfocus: 1if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border"); 因此,如果它没有该类(读取:div中没有??元素具有焦点),则删除边框。否则,没有任何反应。 没有:焦点,但有:选择 http://docs.jquery.com/Selectors/selected 但是如果你想根据选择的内容改变事物的外观,你可能应该使用模糊事件。 http://docs.jquery.com/Events/blur 相关讨论 有:focus api.jquery.com/focus-selector 据我所知,你不能问浏览器屏幕上的任何输入是否有焦点,你必须设置某种焦点跟踪。 我通常有一个名为"noFocus"的变量并将其设置为true。然后我将焦点事件添加到使noFocus为false的所有输入。然后我将一个模糊事件添加到将noFocus设置为true的所有输入。 我有一个很容易处理这个问题的MooTools类,我相信你可以创建一个jquery插件来做同样的事情。 创建完成后,您可以在进行任何边框交换之前检查noFocus。 跟踪两个状态(悬停,聚焦)为真/假标志,每当更改时,运行一个函数,如果两者都为假,则删除边框,否则显示边框。 所以:onfocus设置focus = true,onblur设置focus = false。 onmouseover sets hovered = true,onmouseout sets hovered = false。在每个事件之后运行一个添加/删除边框的函数。 简单 12345678910 <input type="text" /> $("input").focusin(function() { alert("I am in Focus"); }); 相关讨论 这并不能告诉您当前关注哪个元素。当新元素获得焦点时调用它。因此,如果一个元素已经具有焦点,并且您想知道'this'是否是那个,那么这段代码就没用了。