Reputation: 673
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
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
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
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