3

这个问题与这个Autocomplete: first item 只有当用户在 tab key 上键入时才聚焦

为了使第一个项目仅在用户使用 jqueryUi 键入 tab 键时聚焦,可以制作类似http://jsfiddle.net/uymYJ/8/ (1) 的内容。

这个实现的坏处是对事件对象的修改event.keyCode = $.ui.keyCode.DOWN;
事实上,通过这种方式,它将影响此事件的所有其他侦听器:稍后运行的 keydown 事件的所有侦听器(包括所有委托的侦听器)将看到 event.keycode 为 $.ui.keyCode.ENTER。

我的问题是:
1)我的担忧是否the modification of the event object合理?如果不是为什么?
2)你能建议另一种方法来达到同样的结果吗?
3)@AaronDigulla 建议的一种选择是使用document.createEvent(). 在这种情况下使用此方法的正确方法是什么?我确实尝试了以下代码(3),但它不起作用。

PS:
这是关于自动完成的代码(2)。


(1)

$("#box").keydown(function(e){
    if( e.keyCode != $.ui.keyCode.TAB) return;

   e.keyCode = $.ui.keyCode.DOWN;
   $(this).trigger(e);

   e.keyCode = $.ui.keyCode.ENTER;
   $(this).trigger(e);

   $(this).siblings("input").select();
});

(2)

function (e) {
    var f = typeof e == "string",
        g = Array.prototype.slice.call(arguments, 1),
        h = this;
    return e = !f && g.length ? a.extend.apply(null, [!0, e].concat(g)) : e, f && e.charAt(0) === "_" ? h : (f ? this.each(function () {
        var d = a.data(this, c),
            f = d && a.isFunction(d[e]) ? d[e].apply(d, g) : d;
        if (f !== d && f !== b) return h = f, !1
    }) : this.each(function () {
        var b = a.data(this, c);
        b ? b.option(e || {})._init() : a.data(this, c, new d(e, this))
    }), h)
}

(3)

$("#box").keydown(function(){

    e = document.createEvent('KeyboardEvent');
    e.initEvent("keydown", true, true);
    $(this).dispatchEvent(e);

    if( e.keyCode != $.ui.keyCode.TAB) return;

   e.keyCode = $.ui.keyCode.DOWN;
   $(this).trigger(e);

   e.keyCode = $.ui.keyCode.ENTER;
   $(this).trigger(e);

   $(this).siblings("input").select();
});
4

1 回答 1

1

你是对的:事件将被修改,所有听众都会看到修改后的键码。

但更重要的问题是:这危险吗?

要回答这个问题,我们需要知道哪些侦听器绑定到该元素。当然,自动完成插件中的所有侦听器都旨在处理这种情况。对他们来说,这没问题。

当您将自己的事件绑定到小部件时,麻烦就开始了。

一种解决方案是创建新事件(使用document.createEvent()+ 复制所有重要属性)并发送克隆以避免修改原始事件。

一些链接:

于 2012-08-21T07:54:44.377 回答