jQuery selector: delegate click event to only tr elements with specific data
I'm trying to delegate a click event to a TR element that contains a TD with a specific attribute, i.e.
<table>
<tr>
<td>product one</td>
<td>price</td>
</tr>
<tr>
<td data-imgurl="images/p2.png">product two</td>
<td>price</td>
</tr>
</table>
The goal is to click on the row and retrieve that row's TD "data-imgurl" attribute value, i.e. the URI for an image. This is just a test to retrieve that value. Ultimately I'd want to have the click handler show the image in a hidden DIV or maybe lightbox, not sure what I want to do yet.
My selector (that works only in that it will assign a click to the actual TD element:
$("table").delegate("tr td[data-imgurl]", "click", function(evt){
alert( $(this).attr("data-imgurl") );
});
Note, the data is created dynamically from a server-side script, and the "data-imgurl" attribute is based on logic in that script, so that only products that actually have images are assigned a "data-imgurl" attribute. Perhaps I'm looking at it all wrong, and should somehow attach the data to the row itself, but that is counter-intuitive.
Or maybe I should be actually pushing the image into a hidden TD and assigning it a class or rel attribute? So it exists on the page but then a click reveals it? The idea still being that only those products with actual images can be clickable.
EDIT Ok, I resolved this by pushing the data into the actual row itself. Makes more sense that way, each row is a record. Solution:
<table>
<tr>
<td>product one</td>
<td>price</td>
</tr>
<tr data-imgurl="images/p2.png">
<td>product two</td>
<td>price</td>
</tr>
</table>
And the jQue开发者_高级运维ry
$("table").delegate("tr[data-imgurl]", "click", function(evt){
alert( $(this).attr("data-imgurl") );
});
I think selecting the row is best as well... jQuery has very powerful selectors, and many ways to do the same thing, ie:
$('tr:has(td[data-imgurl])').click(function(evt){
// stuff here...
});
Yep, I'd push it onto the row. This data defines the product, which is represented by a row, not a cell.
Regardless, if you weren't using delegate
, it would be easy to put the click event onto the row.
$('table tr td[data-imgurl]').parent().click(function (evt) {
// on tr click
});
With delegate
, however, things get messier, and I'm not immediately sure if one can do it that way.
The way your currently setting up your script is a completely fine way to attach the event. Where you store the data is arbitrary, but the way you access it can grant you performance benefits.
The only piece I would change is the selector syntax. Since you're dynamically adding the attribute "data-imgurl", also add a css class. This can be any class of your choosing as follows:
<td data-imgurl="images/p2.png" class="myProduct">product two</td>
Then, you can access this with the following selector:
$("table").delegate("tr td.myProduct", "click", function() {
alert($(this).attr("data-imgurl"));
//or if you have the metadata plugin
//alert($(this).metadata().imgurl);
});
The reason I would change the selector is the way jQuery checks for attributes. Avoiding the use of attributes in the selector for a large number of items is an easy way to speed up the js execution.
The idea of lazy loading images(as you have it now) is a great idea especially if you do have a large number of products. I like what you did there ;)
A note on "delegates" vs attaching a click event to the object directly: A delegate is fine in this scenario and is recommended if you are dynamically adding rows/cells to be clicked later on.
精彩评论