是否可以获取"current"或"last"事件的事件对象,而无需在处理程序中将其作为参数接收?



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

在代码的某一点上,我需要知道是否按下了Shift键。如果这个库中的事件处理程序写得正确,它会收到"event"作为它的第一个参数,但不幸的是,它没有(事件与HTML中的onclick内联连接)

所以,我想看看jQuery是否将最后一个事件对象"存储"在某个地方,或者是否有其他方法可以访问它

本质上,我想要的是"window.event",但理想情况下我希望它能在Firefox上运行。

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

你能包装他们用作事件处理程序的函数吗?举个人为的例子:

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!)
}

如果可以进入函数内部,还可以检查arguments对象。你的活动对象应该在那里(我认为是第一个项目)。

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(…))。如果不是这种格式,那么这个确切的代码将不起作用:)

正如我在评论中提到的,在非IE的浏览器中可以使window.event存在。它需要包装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);
}

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

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

根据实际的呼叫链,可能需要多次遍历.caller

在IE6、IE11和最新Chrome上进行了测试。应该也适用于大多数其他浏览器。

另请参阅如何在JavaScript中找到调用方函数?。

最新更新