1

have dumb question.

Here I've got three events calling the same function, connected to the same <div>:

<html>
<head>
<script type='text/javascript'>
function universal_action_handler( event ) {
  var eType = event.type;
  var eTarget = event.target || event.srcElement;
  console.log( "Captured Event, type=", eType, ", target=", eTarget );
  if( 'mouseover' == eType ) {
    console.info( "onMouseOver: set background color to red." );
    eTarget.style.backgroundColor = 'red';
    eTarget.style.fontSize = '';
  }
  if( 'mouseout' == eType ) {
    console.info( "onMouseOut: set background color to transparent." );
    eTarget.style.backgroundColor = 'transparent';
    eTarget.style.fontSize = '';
  }
  if( 'click' == eType ) {
    console.info( "click!" );
    eTarget.style.fontSize = 'larger';
  }
}
</script>
</head>
<body>

<div style='border: 1px dashed red; display: inline-block;'
 onClick="universal_action_handler(event);"
 onMouseOver="universal_action_handler(event);"
 onMouseOut="universal_action_handler(event);">Click me!</div>

</body>
</html>

I have onClick='', onMouseOver='', and onMouseOut='', all connected to the same <div>, and all calling the same function. If I want to add an event, I have to add an onEventThingy='' and call the same universal action handler function above. Inside the function, it decides what kind of event (event.type) and takes action.

Is there an onAnything='' event that I can use to call the universal function for any event which may happen to that <div>?

user965641
  • 137
  • 1
  • 1
  • 11
  • I'm not sure, but this doesn't seem like a good idea. What are you really trying to do? If your issue is duplication of code between your `if` blocks (e.g. if two events will execute the same code), use a `switch` statement instead. – Anson Sep 27 '11 at 00:38
  • Btw you'll need `event = event || window.event;` also. – Šime Vidas Sep 27 '11 at 00:43
  • Anson: no, it's probably not a good idea. Yes, I can use a `switch` statement, but that's not what I'm asking about. All I wanted to know is if there were any kind of "onAnything" or "onUniversal" event thingy. I may use jQuery, don't know yet. Just asking dumb questions. – user965641 Sep 27 '11 at 00:53
  • Worth checking out: http://stackoverflow.com/questions/5107232/is-it-possible-to-programmatically-catch-all-events-on-the-page-in-the-browser – Šime Vidas Sep 27 '11 at 01:05
  • @ŠimeVidas: You don't need `event = event || window.event;` if you're passing the full word `event` from inline on[event] handlers. – user113716 Sep 27 '11 at 01:06
  • @user965641 - If you're interested in jQuery, see [`.bind()`](http://api.jquery.com/bind/), which allows you to bind multiple events at one time. See the **Multiple Events** section down the page. – Jared Farrish Sep 27 '11 at 01:12

5 Answers5

7

Instead of all those onevent attributes (which should be avoided anyway), you could set the onevent properties on the DOM element like so:

div.onclick = div.onmouseover = div.onmouseout = universal_action_handler;

where div is a reference to your DIV element.


Btw this is how I would implement the handler:

function universal_action_handler ( e ) {
    var target, style;

    e = e || window.event;
    target = e.target || e.srcElement;
    style = target.style;

    if ( e.type === 'click' ) {
        style.fontSize = 'larger';
    } else {
        style.backgroundColor = e.type === 'mouseover' ? 'red' : 'transparent';
        style.fontSize = '';   
    }
}

Live demo: http://jsfiddle.net/rPVUW/

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
2

No, there's no way to attach the same handler to all possible events. Is that really what you want? This could lead to your handler containing a huge if..else block or big switch statement.

If you want to attach common functionality (logging in your example) to all event handlers, consider this JavaScript:

function logAndHandle(event, innerHandler) {
    var eType = event.type;
    var eTarget = event.target || event.srcElement;
    console.log( "Captured Event, type=", eType, ", target=", eTarget );        
    return innerHandler(event);
}

Which you'd use like this:

<div onclick="logAndHandle(event, yourClickHandler);"
     onmouseover="logAndHandle(event, yourMouseOverHandler);"
     onmouseout="logAndHandle(event, yourMouseOutHandler)">Click me!</div>
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • That structure seems like a good idea to apply the same set of actions to each of several events, then continue execution to custom event functions. Bravo! – user965641 Sep 27 '11 at 00:56
2

No, there is no universal event.

You can try what Šime Vidas suggested, or some libraries (e.g., jQuery) allow you to bind multiple events to the same handler with a single line of code, but either way you do need to explicitly list out the events to be bound.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • I was afraid of that. So then, jQuery must simply loop through each specified event, adding each to the specified object, kinda like what I was doing manually. – user965641 Sep 27 '11 at 00:58
2

Given that you seem to want some functionality to run for all events, and other functionality to be specific to particular events, I'd combine Jacob's answer with Šime Vidas's:

var log = function(innerHandler) {
    return function(event){
        var eType = event.type;
        var eTarget = event.target || event.srcElement;
        console.log( "Captured Event, type=", eType, ", target=", eTarget );
        return innerHandler(event);
    };
};

And use it thus:

div.onclick = log(yourClickHandler);
div.onmouseover = log(yourMouseOverHandler);
div.onmouseout = log(yourMouseOutHandler);

Currying the log function makes it very easy to compose future "all event" functionality:

var count = function(innerHandler){
    var totalCount = 0;
    return function(event){
        totalCount += 1;
        alert("I've been called " + totalCount + " times.");
        return innerHandler(event);
    };
};

div.onclick = count(log(yourClickHandler));

Anyway, if you want to do functional-style programming in Javascript, you'd also want to look at Function.apply and Function.call.

Zach Snow
  • 1,014
  • 8
  • 16
1

Using just javascript, no, there is no 'onAnything' attribute. If you have the ability to add jQuery, you can 'bind' multiple events to the same div and then run the same function.