Cum să selectați jQuery <td> cu o singură casetă de selectare în el

Scopul

I want to select <td> elements that contain only a checkbox. I want to do this with a single selector (not using chaining or logic outside the selector) so that I can use the selector with jQuery functions like live or delegate.

The bigger pictures is that I want to listen for a click event on these <td>s and pass the click event on to the checkbox, thus creating a larger clicking area. This is important, because the <tr> also has a different click event that I don't want to activate when users click and miss the checkbox.

The specifics

I created a jsfiddle with an example scenario: http://jsfiddle.net/ytA3X/

This is what I started with that is not working. In other words, select any td element that has a checkbox but does not have anything that is not a checkbox.

$('td:has(:checkbox):not(:has(:not(:checkbox)))')
=> []

:not(:has(...)) works in my jsfiddle example.

:has(:not(...)) works in my jsfiddle example.

:not(:has(:not(...))) always seems to select nothing.

Is there a different way that I can select td elements with only a checkbox, or am I doing something wrong?

5
Orice motiv anume pe care nu îl folosiți pentru a mări zona de clic? De ce folosiți și o masă? Datele pe care le prezentați sunt tabele?
adăugat autor Madara Uchiha, sursa
Da, este un tabel de date. Asta este cu adevărat irelevant la întrebare - nu trebuie să fii poliția de masă. Chiar dacă aș folosi alte elemente, aș mai avea aceeași problemă. Ce spuneai despre creșterea zonei de clic? Se pare că ai lăsat un cuvânt care ar fi putut face acest comentariu util ;-)
adăugat autor Edward Anderson, sursa
Deci, care este întrebarea dvs., doriți să selectați td care are un singur element de casetă de selectare și niciun alt element?
adăugat autor Selvakumar Arumugam, sursa

4 răspunsuri

Ce zici de folosirea : only-child :

$('td:has(:checkbox:only-child)')...

JSFiddle

8
adăugat
+1 Nisa, nu stiam jQuert sustine acest selector css3. Dar nu aș folosi-o din motive de citire.
adăugat autor gdoron, sursa
Poate. Nu-mi place prea mult : în selectorii mei. Dar mi-a plăcut răspunsul!
adăugat autor gdoron, sursa
Mulțumiri! Acesta este exact același răspuns mai simplu pe care îl căutam.
adăugat autor Edward Anderson, sursa
@ gdoron: Readability? Se spune: "selectați toate elementele td care au ca only-child ". Puteți să o citiți cu ușurință ca o propoziție.
adăugat autor Evan Mulawski, sursa
+1 A fost foarte util pentru mine .. Mulțumesc
adăugat autor chespinoza, sursa

Nu faceți acest lucru cu un singur selector, va face codul greu de citit și extrem de greu de întreținut și depanat.

$('td:has(input[type="checkbox"])').filter(function(){
    return $(this).children().length === 1
});

Live DEMO

2
adăugat
@nilbus adaugă o clasă tuturor elementelor care se potrivesc în delegare.
adăugat autor Madara Uchiha, sursa
@Vega. Ai dreptate, în acest caz, este doar un obicei bun ... :) Sfârșit.
adăugat autor gdoron, sursa
@Vega. Nu aveți nevoie de , dar === este mai rapid decât == , iar întotdeauna numai acest operator de comparare vă poate salva de la probleme .
adăugat autor gdoron, sursa
@Vega. Ar trebui să citiți acest subiect
adăugat autor gdoron, sursa
@nilbus. Ce versiune jQuery folosiți? de ce utilizați în continuare funcția live depreciată?
adăugat autor gdoron, sursa
@nilbus: Ce vrei să spui? Încă poți să lansezi .live după apelul la .filter .
adăugat autor mellamokb, sursa
Din documentele jQuery: "Metodele de înlănțuire nu sunt acceptate. De exemplu, $ (" a ") găsește (" offsite, .external ") live (...) nu este validă și nu funcționează așa cum era de așteptat. " Cu excepția cazului în care filtrul este special, sunt destul de sigur că nu funcționează.
adăugat autor Edward Anderson, sursa
@ aplicația utilizează 1.4.4 unde .on nu este încă disponibil. Ezităm să îmbunătățim până când am timp să încerc bine.
adăugat autor Edward Anderson, sursa
Dar atunci nu pot folosi delegat sau trăiesc pentru a urmări evenimentul clic cu un formular dinamic.
adăugat autor Edward Anderson, sursa
@gdoron Înțeleg complet și sunt de acord că folosirea === este mai bine .. dar Ceea ce am încercat să spun este === nu este mai rapid dacă tipurile sunt același lucru și nu este cel mai bun în acest caz specific așa cum ați menționat .. Pentru a fi sincer, nu este nici măcar o problemă să fiți discutat atât de mult> .. Doar încercând să vă explic ceea ce am vrut să spun.
adăugat autor Selvakumar Arumugam, sursa
@gdoron Este adevărat că === este mai rapid decât == ? >> jsperf.com/equals-operator <<. Sunt de acord că utilizarea === este mai bună, dar nu în acest caz specific.
adăugat autor Selvakumar Arumugam, sursa
Chiar trebuie să faceți o verificare === pentru proprietatea lungime?
adăugat autor Selvakumar Arumugam, sursa

Puteți folosi selectorul numai-copil :

$('td:has(:checkbox:only-child)')

Here it is in use with your markup.

2
adăugat
Mulțumiri! Acesta este exact același răspuns mai simplu pe care îl căutam.
adăugat autor Edward Anderson, sursa
+1 Aveați 44 de secunde mai lent, dar meritați încă câteva puncte pentru a vă gândi la : only-child .
adăugat autor Evan Mulawski, sursa

Puteți folosi pur și simplu .not și o împărțiți în două selectori separați:

http://jsfiddle.net/ytA3X/1/

1
adăugat
Acest lucru va funcționa și cu două casete de bord, dar nu sunteți sigur că aceasta este ieșirea pe care o dorește.
adăugat autor gdoron, sursa