3

Current Code

<a onclick="callMe1()">Click Me</a>
<a onclick="callMe2()">Click Me 2</a>

function callMe(){
   //anything
}

function callMe2(){
   //anything
}

and so on... I have hundreds of onclick event functions.

I want to add this function which should be called before any onclick event function.

function callBeforeAnyOnClick(){
//This should be executed before callMe() and callMe2().
//once execution is complete, it should call a function as per onclick event,callMe() or callMe2().
}

Any solution? Will jquery bind work here?

Mojilo
  • 31
  • 3
  • 1
    Please stop doing inline JS. – PeeHaa Dec 04 '12 at 12:56
  • 1
    @PeeHaa: While inline script is not unobtrusive, can't really be unit tested and does not separate functional logic from the DOM it is a perfectly acceptable way to reference method to execute. So simply telling someone to stop doing it is rubbish if they don't need the benefits of separating it out or the project is a small proof of concept app or similar. You cannot make a statement like this without knowing all circumstances. One can however advise of the benefits when not using in-line script which is not relevant though to the question. – Nope Dec 04 '12 at 12:58
  • 4
    @PeeHaa unhelpful. It may be out of his control to do so. – Eli Gassert Dec 04 '12 at 12:59
  • 2
    I doubt whether that's possible, the inline click handler will always go first. – Ja͢ck Dec 04 '12 at 13:01

3 Answers3

0

you could call a "dispatcher" function passing the real function you need to call, e.g.

<a onclick="callfun(f1)">Click Me</a>
<a onclick="callfun(f2)">Click Me 2</a>

function f1 { console.log("Hello f1"); }
function f2 { console.log("Hello f2"); }

function callfun(f){
   /* do something before */

   if ('function' === typeof f) {
     f();
   }
}
Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177
0

The way the DOM + JS works, you can't "hijack" the order of execution when mixing/matching library (jquery) event handling and inline script event handling. Two things come to mind:

  1. Use a mousedown/up event, which will fire before the click event.
  2. Modify/manipulate the DOM with jquery after load so you have more control.

Pseudo Example of option #2:

$(function()
{

  $('a[onclick]').click(function() { /* your normal on click here */ });

  // now modify the DOM to convert the onclick attr into a function call
  $('a[onclick]').each(function()
  {
    var clickFunction = $(this).attr('onclick');

    // remove the attr
    $(this).attr('onclick', '');

    // might be a better way than calling eval on the inline function, but this serves its purpose for the demo
    $(this).click(function() { eval(clickFunction); });
  });
});

So in the above example, I remove the onclick attr and conver it to a jquery click event handler, and I do it second, not first, so it happens after my newly inserted pre-onclick function.

Eli Gassert
  • 9,745
  • 3
  • 30
  • 39
  • go ahead and put a demo together. You can change the order of events *bound with jquery* but not ones *not bound with jquery*. So in this case, the inline `onclick` will happen first, no matter what order you add for `events`. I've had this same issue and I also tried what you're suggesting. `onclick` still takes priority unfortunately. – Eli Gassert Dec 04 '12 at 13:10
0

What you are looking for is the classic example of the Observer Pattern. This is quite hard to achieve in javascript, specially if one mixes JS with jQuery, and also because what you want to listen are events (in itself, already observers). I would add a listener on the document and only execute it when there was a defined onclick function for the element (note: this will not work if you add the event listener using .on from jQuery):

function observerMethod(e) {
  if (e.target.onclick) {
    ... do your thing here ...
  }
}

document.addEventListener("click", observerMethod, false);
ChuckE
  • 5,610
  • 4
  • 31
  • 59