我正在尝试修改行为或JavaScript库,基本上是通过monkeypatching它(不,没有更好的方法)。
在代码中的某个点,我需要知道Shift是否被按下。如果这个库中的事件处理程序是正确编写的,那么它会接收“event”作为它的第一个参数,但不幸的是,它不是(事件是通过HTML中的onclick内联连接的)
所以,我试图看看jQuery是否“存储”某个地方的最后一个事件对象,或者是否有其他方法可以访问它。
基本上,我想要的是“window.event”,但理想情况下我希望它可以在Firefox上运行。
除了在文档中添加全局onKeyDown处理程序并自己跟踪Shift的状态之外,还有什么想法吗?根据我的口味,这感觉有点矫枉过正,有点过于全球化。
答案 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上进行了测试。应该也可以在大多数其他浏览器上使用。