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

23 javascript jquery jquery-ui jquery-ui-autocomplete

我正在使用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');
    }
});
Run Code Online (Sandbox Code Playgroud)

谢谢

Ric*_*gan 7

我能想到这样做的唯一方法是让一个处理程序监听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);
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • keydown 事件更可靠,我认为 (2认同)

Nic*_*k F 6

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

if (whatInput.ask() === 'mouse') {
  // do something
}
Run Code Online (Sandbox Code Playgroud)

...还有(通过它添加到文档的单个数据属性body)样式:

[data-whatinput="mouse"] :focus,
[data-whatinput="touch"] :focus {
  // focus styles for mouse and touch only
}
Run Code Online (Sandbox Code Playgroud)

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


小智 5

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

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

  • `event.originalEvent.originalEvent.type`给了我`在Chrome v34中无法读取属性'type'of undefined` (2认同)
  • 截至 2020 年 11 月,这种方法似乎在 Chrome、Firefox、Safari 和 Edge 上完美运行。尽管 Firefox 文档说不支持,但它还是受支持的。 (2认同)