简体   繁体   中英

jquery only selecting first element

I'm trying to add button and click listener to every save span on a page. I do:

$("#save").button().click(function(){
   currentSlide++;
   loadPage();
}

loadPage clears my dialog box and loads the next slide into the box. If I don't add that code to the load page function, only the first save button is assigned the button and click listener. Why do i need to assign the listener every time. Shouldn't jQuery assign the button and click listener to all #save?

All the slides are stored on the page. Load page takes the hidden content and appends it to the dialog box.

Id must be unique for all elements!!!

You have defined an ID selector for you bind to click function. There should only be one ID for each element therefor $('#save') will only bind to one element (the first one). If you want to bind to all spans used in this way then add a class to each span and reference it this way, using a class selector

$('span.mysave')

First, you should not have more than one element on a page sharing the same id attribute.

The id attribute is reserved to be a unique identifier for a single element in a page.

I would recommend adding a class to your elements instead of relying on matching ids.

Secondly, if you are dynamically adding elements to the page, use .live('click', ...) instead of .click() to be able to work with current and future elements added to the page.

// note selecting class ".save" instead of id "#save"
$(".save").button().live('click', function(){
   currentSlide++;
   loadPage();
}

# means id and id='save' is valid for only one element per document (one id 's value can't be used more than once ). Use class='save' instead and use

$(".save").button().click(function(){

save is an ID and as such should only be once on a page. $('#save') maps to document.getElementById('save') which returns one element.

If you are loading loading content you should use live or delegate .

#save is an ID. IDs are supposed to be unique. jQuery assumes this and only gets the 1st element. Instead of an ID, use a class.

Think of the name, class, and ID attributes like this:

  • Elements can have a one name, but they don't have to be unique. Multiple elements can have the same name
  • Elements can be in or more classes. Multiple elements can be in the same class.
  • IDs is a unique ID for that element.

I have a feeling that you're using the id save more than once on the page. At the least, using #save as a jQuery selector will only select one element due to it being an ID.

Replace id="save" with class="save" and use .save to select it with jQuery - classes can be used multiple times, and even multiple classes used on one element.

Unlike the other replies, I am guessing that by 'first' save button you mean that you are replacing the contents of an ancestor of the element with id="save" when you loadPage() .

If this is the case the original 'save button' element that jQuery bound to when you called click() has been destroyed and replaced with a new one that jQuery doesn't know about. Only the elements that were selected when you first created the selector are bound to; it does not update when you change the set of elements that would match.

So after calling loadPage() you would have to call click() to bind the function again (and also button() again, since that changed the old element so would need to be directed to update the new one too).

If you want to bind an event to “any element now or in the future that has id save ” then what you want is event delegation ( delegate() , or its questionable cousin live() ):

$(document.body).delegate('#save', 'click', function(){
    currentSlide++;
    loadPage();
});

Though this doesn't allow you to re-call button() .

What others have said is true, jQuery will return the first ID. But, that's not always the case. Run this test code to see:

<script type="text/javascript" src="/scripts/jquery-1.6.1.min.js"></script>
<script type="text/javascript">
    $(function() {
        $("div").click(function() {
            //$("#a", $("div")).remove(); // 1
            $("#a").remove();             // 2
        });
    });
</script>

<div style="border: solid 1px black;">
    <p id="a">I am the first paragraph.</p>
    <p id="a">I am the second paragraph.</p>
</div>

When you run line 2, it takes away the first #a. Running line 1 removes them both. So if you can't change the markup to use classes instead, sub selecting might be the answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM