Santoo
Santoo

Reputation: 673

How to access the attached event handler in jquery?

I have a simple button in HTML like this:

<input type='button' id='btnPrint' value='Print' onclick="changeStylesheet();" />

This button already contains a onclick event handler. What I m trying to achieve here is to be able compose the onclick event handler for same the button. I would like to add second method that tracks how many times the button was hit.

some approaches:

First: Append another function call in HTML as per inline event registration.

<input type='button' id='btnPrint' value='Print' onclick='changeStylesheet();trackThis();>' />

This is the easiest way to go but not feasible in my situation.

Second: Grab the onclick event and check if it is undefined. Then, recompose the event handler with anonymous function using JavaScript native syntax.

var elem = document.getElementById('btnPrint');
var existingHandler = **elem.onclick ? elem.onclick : function () {};**
elem.onclick = function () {
     trackThis();
     existingHandler();
};

Third: Though above approaches work, I m curious to learn the way to do above #2 approach but with jQuery syntax.

 var elem = $('#btnPrint');
    var existingHandler = **elem.click ? elem.click : function () {};**
    elem.click(function () {
        trackThis();
        existingHandler()
    });

What is happening with #3 solution in mine is that I m getting Uncaught TypeError: Object [object Window] has no method 'trigger' error.

Any hints will be very appreciated.

Upvotes: 0

Views: 1219

Answers (2)

Beetroot-Beetroot
Beetroot-Beetroot

Reputation: 18078

If both handlers are to be attached in jQuery then simply set two click handlers. Internally, jQuery implements an "observer pattern" such that it aggregates handlers and will execute them sequentially in the order they were added.

$('#btnPrint').on('click', firstHandler);
$('#btnPrint').on('click', secondHandler);

These statements need not be consecutive or even in the same scope.

The same principle applies if a handler is already specified in the HTML. jQuery will simply execute any additional handlers after the original.

HTML:

<input type='button' id='btnPrint' value='Print' onclick=".....;" />

jQuery:

$('#btnPrint').on('click', secondHandler);

See fiddle

EDIT ...

It is also possible to revere the order such that the original handler executes after a handler attached in jQuery :

var $btnPrint = $('#btnPrint');
var originalHandler = $btnPrint.get(0).onclick;
$btnPrint.get(0).onclick = null;

$btnPrint.on('click', secondHandler);
$btnPrint.on('click', originalHandler);

See fiddle

Upvotes: 2

Jashwant
Jashwant

Reputation: 29025

If I understand your question right,

This should work,

$('#btnPrint').off("click", "**" ).on('click',function(){
     trackThis();
     existingHandler(); 
})

i.e. first off the existing event handlers , then on your custom one.

If this doesnt help you, this may be the one you want,

How to check if an event handler exist using jQuery or JS?

Edit

If you want to override the inline onclick, you can use this dirty approach.

jQuery code:

$(function(){ 
        var mydiv = $('#mydiv');
        var inlineClick = mydiv.attr('onclick');

        mydiv.removeAttr('onclick').click(function(){
            // your code 
            alert('mycode');

            eval(inlineClick);

            // or first do, eval(inlineClick);
            //then your code later

        })
    });     
    function inlinefun(){
        alert('I am inline function'); 
    }

Markup:

<div id='mydiv' onclick='inlinefun();'>Mydiv</div> 

Without 'evil' eval

(may not work in every situation, just gave a you direction)

$(function(){ 
        var mydiv = $('#mydiv');

            // Dirty way to get function name and its args by a string.
    var inlineClick = mydiv.attr('onclick').split('(');
    var funName = inlineClick[0];
            var args = inlineClick[1].replace(')','');


    mydiv.removeAttr('onclick').click(function(){
        // your code 
        alert('mycode');  

        // The default inline function
        window[funName](args);

        // you can change the order as you want

    })
});     
function inlinefun(msg){
            // I know I am passing string, so removing the quotes, you need a generalised approach here
    alert(msg.replace('"','')); 
}

Markup:

<div id='mydiv' onclick='inlinefun("I am inline function");'>Mydiv</div> 

Upvotes: 0

Related Questions