区分键盘/鼠标触发的焦点事件

我正在使用jquery ui自动完成,并希望在键盘交互和鼠标交互触发的焦点事件之间进行解密。 我怎么会这样呢?

$('input').autocomplete({ source: function(request, response) { ... }, focus: function(event, ui) { // If focus triggered by keyboard interaction alert('do something'); // If focus event triggered by mouse interaction alert('do something else'); } }); 

谢谢

我能想到这样做的唯一方法是让一个处理程序监听keypressclick事件,并打开/关闭一个布尔标志。 然后在输入的focus处理程序中,您可以检查标志的值是什么,然后从那里开始。

可能是类似的东西

 var isClick; $(document).bind('click', function() { isClick = true; }) .bind('keypress', function() { isClick = false; }) ; var focusHandler = function () { if (isClick) { // clicky! } else { // tabby! } } $('input').focus(function() { // we set a small timeout to let the click / keypress event to trigger // and update our boolean setTimeout(focusHandler,100); }); 

在jsFiddle上制作了一个小型工作原型(难道你不喜欢这个网站吗?)。 如果你愿意,请查看。

当然,这都是在上运行focus事件,但自动完成的focus处理程序以相同的方式工作。

setTimeout会引入一些延迟,但在100ms时,根据您的需要可能会忽略不计。

实际上,您应该能够从传递给焦点事件的event-Object中确定这一点。 根据您的代码结构,这可能会有所不同,但通常会有一个名为originalEvent的属性,它可能嵌套到某个深度。 更仔细地检查event以确定正确的语法。 然后通过正则表达式对mousenterkeydown进行测试。 像这样的东西:

 focus: function(event, ui){ if(/^key/.test(event.originalEvent.originalEvent.type)){ //code for keydown }else{ //code for mouseenter and any other event } } 

我发现实现这一目标的最简单,最优雅的方法是使用“ 什么输入? ”库。 它很小(约2K缩小),并允许您在脚本中访问事件类型:

 if (whatInput.ask() === 'mouse') { // do something } 

…以及(通过它添加到文档body的单个数据属性)样式:

 [data-whatinput="mouse"] :focus, [data-whatinput="touch"] :focus { // focus styles for mouse and touch only } 

我特别喜欢这样一个事实:你只想要一个不同的鼠标/键盘视觉行为,它可以在样式表(它真正属于的地方)中这样做,而不是通过一些hacky bit事件检查Javascript(当然,如果你确实需要做一些不仅仅是纯粹的视觉效果,前一种方法可以让你用Javascript来处理它。

首先想到的是你可以找到鼠标的位置并检查它是否在元素的位置

用它来存储元素的位置:

 var input = $('#your_autocompleted_element_id'), offset = input.offset(), input_x = offset.top, input_y = offset.left, input_w = input.outerWidth(), input_h = input.outerHeight(); 

然后使用它来查找窗口内鼠标的绝对位置:

 var cur_mx, cur_my; $(document).mousemove(function(e){ cur_mx = e.pageX; cur_my = e.pageY; }); 

然后在您的自动完成设置中:

 focus: function(event, ui) { // mouse is doing the focus when... // mouse x is greater than input x and less than input x + input width // and y is greater than input y and less than input y + input height if (cur_mx >= input_x && cur_mx <= input_x + input_w && cur_my >= input_y && cur_my <= input_y + input_h) { // do your silly mouse focus witchcraft here } else { // keyboard time! } }