whatf
whatf

Reputation: 6468

finding a class within the same div with jquery

I want to find a class corresponding to another class within the same div.

HTML structure:

<div class="main">
  <div class="party">
                <a href="#"><img id="1001" class="vote" src="http://img2.jpg"></a>
                <p class="votenums"> 20 votes.</p>
  </div>

   <div class="party">
                <a href="#"><img id="1001" class="vote" src="http://imgtwo2.jpg"></a>
                <p class="votenums"> 30 votes.</p>
  </div>

jQuery code is:

$(function() {
    $(".vote").live("click", function(e) {
        e.preventDefault();
        $(this).find(".votenums").text("changed text");
    });
});

When I click img with class vote I want to edit the class votenums, corresponding to the same div. meaning, the desired behavior is, when the image is clicked the text should change.

fiddle is here: http://jsfiddle.net/85vMX/1/

Upvotes: 4

Views: 8239

Answers (3)

gdoron
gdoron

Reputation: 150313

find searches down, and .votenums isn't a descendant of .vote you should traverse up to the div and then find the descendant .votenums

$(function() {
    $(".vote").live("click", function(e) {
        e.preventDefault();
        $(this).closest('div').find(".votenums").text("changed text");
    });
});

If the div you want will always has class=party you can search by it:
$(this).closest('.party').find(".votenums").text("changed text");
Class selector is better than element selector

JSFiddle DEMO

find:

Description: Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.

closest:

Description: Get the first element that matches the selector, beginning at the current element and progressing up through the DOM tree.

Upvotes: 11

JFK
JFK

Reputation: 41143

Unless you have a good reason to set the class and ID to the img element, my suggestion would be to go for a tidier html code. After all, it doesn't make sense to apply .preventDefault() on the img tag since not event is expected, in that case this is what the <a> tag is used for so:

<div class="main">
 <div class="party">
  <a id="1001" class="vote" href="#"><img src="http://2.bp.blogspot.com/_XeuZ1yDnv4Q/TSUkAT6T1dI/AAAAAAAADR8/nPHP4JvVxy8/s1600/vote.jpg"></a>
  <p class="votenums"> 20 votes.</p>
 </div>
 <div class="party">
  <a id="1002" class="vote" href="#"><img src="http://bgathinktank.files.wordpress.com/2011/01/vote-button.jpg"></a>
  <p class="votenums"> 30 votes.</p>
 </div>
</div>

Notice that I set a different ID for each link above since it's not a good idea to use the same ID for two different elements within the same document. IDs should be unique.

Then your best move would be to upgrade to jQuery v1.7.x (if you haven't yet) and use jQuery .on() instead of .live(). You will find this on the jQuery site:

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live(). ... there is also a good article to read here

Then you could use a less costly function like

$(function() {
 $(".vote").on("click", function(e) {
 e.preventDefault();
 $(this).next('.votenums').text("changed text");
 });
});

And last, the css would need a little tweak too

.vote img{
    height:70px;
    width:70px;   
}

Upvotes: 0

mu is too short
mu is too short

Reputation: 434955

An easy and robust approach is to go back up to .party using closest and then come back down using find:

$(".vote").live("click", function(e) {
    e.preventDefault();
    $(this).closest('.party').find('.votenums').text("changed text");
});

That lets you change the internal arrangement of .party without breaking your jQuery.

Upvotes: 1

Related Questions