开发者

jQuery selector: delegate click event to only tr elements with specific data

开发者 https://www.devze.com 2023-01-06 09:12 出处:网络
I\'m trying to delegate a click event to a TR element that contains a TD with a specific attribute, i.e.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消