jQuery: Event Delegation question

My question pertains to the code snippet below. My question is enclosed in /****** comments *******/. Thanks.

<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<!--<script src="../../_scripts/utils.js"></script>-->
<style>
    #gridContents tr {
        background: lightgray;
        cursor: pointer;
        -webkit-user-select: none;
        -moz-user-select: none;
        -o-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
</style>
<script>
$(function() {
    /*****************************************************
     MY QUESTION IS OVER HERE. 
    #gridContents is an id to a <table>, and I'm using event delegation
    so that it would capture any clicks on its <tr> and <td> child elements.
    Problem is, the 'this' is always the <table> node. How do I get the actual
    node that was clicked? In other words, if I clicked a <td> cell, I'd like
    to get a reference to that <td> node; from there, I can get its parent() and get the 
    <tr> node, which is my real goal.
     *****************************************************/
    $("#gridContents").click(function(event) { // My event delegation
        console.log($(this).prop("tagName")); // No matter what I click, this just prints TABLE, but I need to know which <tr>/<td> tag was clicked. How do I get that?
    });
});
</script>
</head>
<body>
<table id="gridContents">
    <tr custID="1"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="2"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="3"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="4"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="5"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="6"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="7"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="8"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="-1"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
    <tr custID="-1"><td>12345</td><td>Doe</td><td>John</td><td>8005551212</td><td>8005551213</td><td>8005551214</td><td>8005551215</td></tr>
</table>
</body>
</html>

Open in new window

elepilAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

SwapnilSoftware ArchitectCommented:
Just replace
$("#gridContents").click(function(event.....

To

$("#gridContents td").click(function(event...

Above will bind event with cell rather than table.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
RobOwner (Aidellio)Commented:
(no points) TR tags cannot be clicked as they are semantic only so go with what's been suggested
0
RobOwner (Aidellio)Commented:
(no points) TR tags cannot be clicked as they are semantic only so go with what's been suggested
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

elepilAuthor Commented:
To netswap and Rob Jurd. Thanks both for responding.

The reason why I'm asking about Event Delegation is because I'm trying to avoid what you're both suggesting. Currently, I have my events attached to the <tr> tags, which is already event delegation because the <tr> tags catch the events of its <td> children. But I needed to elevate this event delegation to the table level because all the <tr> (and <td>'s within them) will be dynamically created; hence, I need to attach the event to a node higher than the <tr> or <td>, and <table> seems appropriate.
0
elepilAuthor Commented:
I guess what I'm wondering is this. If I used:

$("#gridContents td").click(function(event...

and the <tr> and <td> tags are constantly getting destroyed and replaced, will there be consequences? Would I end up accumulating event handlers with null targets? I know this is the case with resize handlers. For example, if I created an resize event handler to a runtime-instantiated <div>, then later removed it from the DOM, I know the resize handler will still exist unless I specifically unbind it before removing the <div>. The last thing I want is to keep accumulating event handlers in the background for <tr> and <td> tags that have already been replaced with a new set. You see what I'm getting at?
0
elepilAuthor Commented:
Well, I found the solution. Here's what I got from the jQuery site:

"Binding events to elements that don't exist yet. This is called event delegation. Here's an example just for completeness, but see the page on Event Delegation for a full explanation."

(I modified their example to work with my code sample)
 $("#gridContents").on( "click", "tr", function() {
        console.log($(this).attr("custID"));
        console.log( "Something in #gridContents was clicked, and we detected that it was <tr> element.");
});

Thanks for responding
0
RobOwner (Aidellio)Commented:
Just be aware that including tr in the event delegation will mean that td events cannot be captured (as the try one is essentially sitting above it). Certainly event delegation is necessary in this case when you're adding and removing elements and you need them to retain the specified events.
0
elepilAuthor Commented:
Rob, I never want to capture events from the <td>'s. This is a data grid type of UI where the user is supposed to select a row. If I wanted to capture the <td> events, I would've done:

 $("#gridContents").on( "click", "td", function() { // Changed the "tr" to a "td"
 });

Thanks for the caveat though.
0
RobOwner (Aidellio)Commented:
Good to hear ;)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.