how to get javaScript event source element?

44

Is there a way to retrieve the element source of an inline javaScript call?

I have a button like this:

<button onclick="doSomething('param')" id="id_button">action</button>

Note:

  • the button is generated from server
  • I cannot modify the generation process
  • several buttons are generated on the page, I have control only on client side.

What I have tried:

function doSomething(param){
    var source = event.target || event.srcElement;
    console.log(source);
}

On firebug I get event is not defined

Edit: After some answers, an override of the event handling using jQuery is very acceptable. My issue is how to call the original onClick function with it's original prameters, and without knowing the function name.

code:

<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>
.
.
and so on..

So the override would be:

$(document).on('click', 'button', function(e) {
  e.preventDefault();
  var action = $(this).attr('onclick');
  /**
   * What to do here to call
   * - doSomething(this, 'param'); if button1 is clicked
   * - doAnotherSomething(this, 'param1', 'param2'); if button2 is clicked
   * - doDifferentThing(this); if button3 is clicked
   * there are many buttons with many functions..
   */
});

This question is tagged with javascript jquery html

~ Asked on 2012-05-03 09:25:35

The Best Answer is


12

You should change the generated HTML to not use inline javascript, and use addEventListener instead.

If you can not in any way change the HTML, you could get the onclick attributes, the functions and arguments used, and "convert" it to unobtrusive javascript instead by removing the onclick handlers, and using event listeners.

We'd start by getting the values from the attributes

_x000D_
_x000D_
$('button').each(function(i, el) {_x000D_
    var funcs = [];_x000D_
_x000D_
 $(el).attr('onclick').split(';').map(function(item) {_x000D_
     var fn     = item.split('(').shift(),_x000D_
         params = item.match(/\(([^)]+)\)/), _x000D_
            args;_x000D_
            _x000D_
        if (params && params.length) {_x000D_
         args = params[1].split(',');_x000D_
            if (args && args.length) {_x000D_
                args = args.map(function(par) {_x000D_
              return par.trim().replace(/('")/g,"");_x000D_
             });_x000D_
            }_x000D_
        }_x000D_
        funcs.push([fn, args||[]]);_x000D_
    });_x000D_
  _x000D_
    $(el).data('args', funcs); // store in jQuery's $.data_x000D_
  _x000D_
    console.log( $(el).data('args') );_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button onclick="doSomething('param')" id="id_button1">action1</button>_x000D_
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>._x000D_
<button onclick="doDifferentThing()" id="id_button3">action3</button>
_x000D_
_x000D_
_x000D_

That gives us an array of all and any global methods called by the onclick attribute, and the arguments passed, so we can replicate it.

Then we'd just remove all the inline javascript handlers

$('button').removeAttr('onclick')

and attach our own handlers

$('button').on('click', function() {...}

Inside those handlers we'd get the stored original function calls and their arguments, and call them.
As we know any function called by inline javascript are global, we can call them with window[functionName].apply(this-value, argumentsArray), so

$('button').on('click', function() {
    var element = this;
    $.each(($(this).data('args') || []), function(_,fn) {
        if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
    });
});

And inside that click handler we can add anything we want before or after the original functions are called.

A working example

_x000D_
_x000D_
$('button').each(function(i, el) {_x000D_
    var funcs = [];_x000D_
_x000D_
 $(el).attr('onclick').split(';').map(function(item) {_x000D_
     var fn     = item.split('(').shift(),_x000D_
         params = item.match(/\(([^)]+)\)/), _x000D_
            args;_x000D_
            _x000D_
        if (params && params.length) {_x000D_
         args = params[1].split(',');_x000D_
            if (args && args.length) {_x000D_
                args = args.map(function(par) {_x000D_
              return par.trim().replace(/('")/g,"");_x000D_
             });_x000D_
            }_x000D_
        }_x000D_
        funcs.push([fn, args||[]]);_x000D_
    });_x000D_
    $(el).data('args', funcs);_x000D_
}).removeAttr('onclick').on('click', function() {_x000D_
 console.log('click handler for : ' + this.id);_x000D_
  _x000D_
 var element = this;_x000D_
 $.each(($(this).data('args') || []), function(_,fn) {_x000D_
     if (fn[0] in window) window[fn[0]].apply(element, fn[1]);_x000D_
    });_x000D_
  _x000D_
    console.log('after function call --------');_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
_x000D_
<button onclick="doSomething('param');" id="id_button1">action1</button>_x000D_
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button2">action2</button>._x000D_
<button onclick="doDifferentThing()" id="id_button3">action3</button>_x000D_
_x000D_
<script>_x000D_
 function doSomething(arg) { console.log('doSomething', arg) }_x000D_
    function doAnotherSomething(arg1, arg2) { console.log('doAnotherSomething', arg1, arg2) }_x000D_
    function doDifferentThing() { console.log('doDifferentThing','no arguments') }_x000D_
</script>
_x000D_
_x000D_
_x000D_

~ Answered on 2012-05-03 09:39:55


33

Your html should be like this:

<button onclick="doSomething" id="id_button">action</button>

And renaming your input-paramter to event like this

function doSomething(event){
    var source = event.target || event.srcElement;
    console.log(source);
}

would solve your problem.

As a side note, I'd suggest taking a look at jQuery and unobtrusive javascript

~ Answered on 2012-05-03 09:31:16


Most Viewed Questions: