最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to get the event object for the "current" or "last" event, witho

programmeradmin1浏览0评论

I'm trying to modify the behaviour or a JavaScript library, basically by monkeypatching it (no, there is no better way).

At a certain point in the code, I need to know whether Shift is pressed or not. If the event handler in this library were properly written, it'd receive the "event" as its first parameter, but unfortunately, it isn't (events are wired with onclick inline in the HTML)

So, I'm trying to see if jQuery "stores" the last event object somewhere, or if there is some other way to access it.

Essentially, what I want is "window.event", but ideally I'd like for it to work on Firefox.

Any ideas, besides adding a global onKeyDown handler to the document and keeping track of the state of Shift myself? That feels a bit overkill and a bit too global for my taste.

I'm trying to modify the behaviour or a JavaScript library, basically by monkeypatching it (no, there is no better way).

At a certain point in the code, I need to know whether Shift is pressed or not. If the event handler in this library were properly written, it'd receive the "event" as its first parameter, but unfortunately, it isn't (events are wired with onclick inline in the HTML)

So, I'm trying to see if jQuery "stores" the last event object somewhere, or if there is some other way to access it.

Essentially, what I want is "window.event", but ideally I'd like for it to work on Firefox.

Any ideas, besides adding a global onKeyDown handler to the document and keeping track of the state of Shift myself? That feels a bit overkill and a bit too global for my taste.

Share Improve this question edited Aug 31, 2014 at 1:45 AstroCB 12.4k20 gold badges59 silver badges74 bronze badges asked Jul 20, 2012 at 19:56 Daniel MagliolaDaniel Magliola 32.5k63 gold badges174 silver badges246 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 2

Can you wrap the function they are using as their event handler? Take this contrived example:

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

We could replace keyDownListener with our own method that accepts the event object.

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

If you can get inside the function, you can also inspect the arguments object. Your event object should be in there (the first item, I believe).

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

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

EDIT (In response to the ment below).

If you can "hijack" the method, here's ONE way you could it. I'm not certain if this is a good approach but if you have all these constraints, it will get you what you want. Basically what this code does is it searches for any elements that have an onclick attribute on them and changes the method signature to include the event object.

We can then wrap the original listener to pull the event object out of arguments and then pass execution back to the original function.

Doing this will get you what you want (I think?). See this code:

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

You can see it working in this fiddle: http://jsfiddle/84KvV/

EDIT 2

If you wanna get really fancy with it, you could even automate the wrapping of the functions. See this fiddle: http://jsfiddle/84KvV/2/.

Please note that this is expecting the function strings to be in a certain format so that it can parse it (functionName(...)). If it's not that in that format, this exact code will not work :)

As mentioned in my ment, it IS possible to make window.event exist in browsers that are not IE. It requires you to wrap attachEvent/addEventListener. It would go something like this:

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

As I said, I'm not sure if this will work for inline event listeners, but it might :) If not, at least it's here as a reference for those looking for something similar.

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

It may be needed traverse .caller several times depending on actual call chain.

Tested this on IE6, IE11 and latest Chrome. Should work on most other browsers too.

See also How do you find out the caller function in JavaScript?.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论