0

I want to listen for events on <p> elements at window or document level as there are too many such elements to attach an onclick event hander for each.

This is what I've got:

window.onload=function()
{
    window.addEventListener('click',onClick,false);
}
function onClick(event)
{
    alert(event.target.nodeName.toString());
}

I need advice on the code above, is it good? And also, how can I check if the clicked element is a <p> element other than checking nodeName? For example, if the <p> element contains a <b> element and that is clicked, the nodeType will be b not p.

Thank you.

Richard JP Le Guen
  • 28,364
  • 7
  • 89
  • 119
Francisc
  • 77,430
  • 63
  • 180
  • 276
  • Is there a particular reason for not using any library? Framework like jQuery or YUI delegate make this simple for you to use. Just curious. – momo Sep 10 '11 at 22:36
  • Hey. The environment this will be running in does not allow loading of external scripts. Only way would be to paste the jQuery code directly in the HTML file, but it seems like an overkill for just this. – Francisc Sep 10 '11 at 22:54
  • 1
    @Francisc: Don't forget older IEs (at least IE 7) which don't have the 'target'-property on the `Event`-object. Use something like `var target = 'target' in event ? event.target : event.srcElement;` [srcElement](http://msdn.microsoft.com/en-us/library/ms534638%28v=vs.85%29.aspx). They also lack the `addEventListener`-method - use [attachEvent](http://msdn.microsoft.com/en-us/library/ms536343%28v=vs.85%29.aspx) instead. – Saxoier Sep 10 '11 at 23:13
  • Thank you Saxoier. This will only be seen by Webkit browsers. Does this apply to them? As I know, only IE has that problem. – Francisc Sep 10 '11 at 23:36
  • 1
    @Francisc: It's only an IE issue. All Webkit-browser support 'element.addEventListener' and 'event.target'. – Saxoier Sep 11 '11 at 00:27

3 Answers3

1

I think it is good, and you can perform checking this way

var e = event.target
while (e.tagName != 'P')
   if (!(e = e.parentNode))
       return
alert(e)
Leonid
  • 3,121
  • 24
  • 31
1

If I was you I'd register for the "load" event in the same way that you are for "click". It's a more modern way of event handling, but might not be supported by some older browsers.

Checking the nodeName is the best way to interrogate the node:

function onClick(event) {
    var el = event.target;
    while (el && "P" != el.nodeName) {
        el = el.parentNode;
    }
    if (el) {
        console.log("found a P!");
    }
}
Paul Grime
  • 14,970
  • 4
  • 36
  • 58
1

Consider this:

(function () {

    // returns true if the given node or any of its ancestor nodes
    // is of the given type
    function isAncestor( node, type ) {
        while ( node ) {
            if ( node.nodeName.toLowerCase() === type ) {
               return true;
            } 
            node = node.parentNode;
        }
        return false;
    }

    // page initialization; runs on page load
    function init() {

        // global click handler
        window.addEventListener( 'click', function (e) {
            if ( isAncestor( e.target, 'p' ) ) {
                 // a P element was clicked; do your thing   
            }
        }, false );

    }

    window.onload = init;

})();

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

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