是否可以获取“当前”或“最后”事件的事件对象,而不将其作为处理程序中的参数接收?

时间:2012-07-20 19:56:40

标签: javascript jquery events keydown

我正在尝试修改行为或JavaScript库,基本上是通过monkeypatching它(不,没有更好的方法)。

在代码中的某个点,我需要知道Shift是否被按下。如果这个库中的事件处理程序是正确编写的,那么它会接收“event”作为它的第一个参数,但不幸的是,它不是(事件是通过HTML中的onclick内联连接的)

所以,我试图看看jQuery是否“存储”某个地方的最后一个事件对象,或者是否有其他方法可以访问它。

基本上,我想要的是“window.event”,但理想情况下我希望它可以在Firefox上运行。

除了在文档中添加全局onKeyDown处理程序并自己跟踪Shift的状态之外,还有什么想法吗?根据我的口味,这感觉有点矫枉过正,有点过于全球化。

3 个答案:

答案 0 :(得分:2)

你可以将他们正在使用的函数包装为事件处理程序吗?拿这个人为的例子来说:

var someObject = {
    keyDownListener: function() {
        alert('something was pressed!');
    }
}

我们可以用我们自己的接受事件对象的方法替换keyDownListener。

var someObject = {
    keyDownListener: function() {
        alert('something was pressed!');
    }
}

var oldKeyDownListener = someObject.keyDownListener;
someObject.keyDownListener = function(event) {
    oldKeyDownListener(); // Call the original
    // Do anything we need to do here (or before we call the old one!)
}

如果你可以进入函数,你也可以检查参数对象。你的事件对象应该在那里(我相信第一项)。

var f = function() {
    console.log(arguments);    
}

f(); //= Logs []
f(1); //= Logs [1]
f(1, 'something'); //= Logs [1, 'something']

编辑(回应下面的评论)。

如果您可以“劫持”该方法,可以使用 ONE 方式。我不确定这是否是一个好方法,但如果你有所有这些限制,它会得到你想要的。基本上这个代码的作用是搜索任何具有onclick属性的元素,并更改方法签名以包含事件对象。

然后我们可以包装原始侦听器以从参数中提取事件对象,然后将执行传递回原始函数。

这样做可以得到你想要的东西(我想?)。看到这段代码:

<强> HTML:

<a href="#" onclick="javascript:myFunction(1, 2, 3);">Click Me</a>​

<强> JavaScript的:

window.myFunction = function(one, two, three) {
    console.log("one: " + one + ", two: " + two + ", three: " + three);
}

var originalMyFunction = window.myFunction;
window.myFunction = function() {
    var event = arguments[arguments.length - 1]; // The last item in the arguments array is our event object.
    console.log(event);        
    originalMyFunction.apply(this, arguments);
}

$('[onclick]').each(function() {
    var s = $(this).attr('onclick');
    var lastIndex = s.lastIndexOf(')');

    var s2 = s.substring(0, lastIndex);
    var s3 = s.substring(lastIndex, s.length);

    var s4 = s2 + ', event' + s3;

    $(this).attr('onclick', s4);
});

你可以看到它在这个小提琴中起作用:http://jsfiddle.net/84KvV/

编辑2

如果你想真的很喜欢它,你甚至可以自动化功能的包装。看到这个小提琴:http://jsfiddle.net/84KvV/2/

请注意,这是期望函数字符串采用某种格式,以便它可以解析它(functionName(...))。如果它不是那种格式,那么这个确切的代码将不起作用:)

答案 1 :(得分:1)

正如我的评论中所提到的,可以使windows.event存在于不是IE的浏览器中。它要求您包装attachEvent / addEventListener。它会是这样的:

var oldAddEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function(type, listener, useCapture) {
    var wrapped = function(event) {
        window.event = event;

        listener(arguments);
    }

    oldAddEventListener.call(this, type, wrapped , useCapture);
}

正如我所说,我不确定这是否适用于内联事件监听器,但它可能:)如果没有,至少它在这里作为那些寻找类似东西的人的参考。

答案 2 :(得分:0)

function eventlessHandler(myVal) {
    var event = window.event || eventlessHandler.caller.arguments[0];
    // some work
}    

根据实际的调用链,可能需要遍历.caller多次。

在IE6,IE11和最新的Chrome上进行了测试。应该也可以在大多数其他浏览器上使用。

另请参阅How do you find out the caller function in JavaScript?