在这种情况下如何避免修改事件对象

时间:2012-08-20 16:54:41

标签: javascript jquery-ui javascript-events jquery

此问题与此Autocomplete: first item focused only when the user type on 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),但它不起作用。

P.S .:
这是关于自动完成的代码(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();
});

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

一些链接: