2010-11-18 3 views
3

Ich schreibe ein GreaseMonkey-Skript mit JQuery.
Manchmal ist die Seite, die ich zeigen Informationen in einem TD ändern mag, also:Jquery: idiomatische Möglichkeit, Element A zu wählen, falls vorhanden, Element B sonst?

<center><table><tr><td> 
Something interesting here.</td></tr>....</table></center> 

während es manchmal Dinge in einem P-Tag zeigt (oder mehrere) innerhalb derselben Tabellenstruktur, also:

<center><table><tr><td> 
<p>Other text about the same interesting thing. 
<p>and maybe some more stuff too.</td></tr>...</table></center> 

Im Moment mache ich zwei verschiedene Selektoren, um die <p> vs. die <td> auszuwählen, aber ich frage mich, ob es eine nette Möglichkeit gibt, nur das P-Tag auszuwählen, wenn es vorhanden ist und das TD sonst in einem einzelnen Jquery-Selektor, da Was ich anhängen möchte, ist in beiden Fällen identisch.

(Wenn ich nur an das unabhängig TD anhängen, die Lage meiner hinaus ändert sich basierend auf der Anwesenheit/Abwesenheit des P-Tag, so dass ich für die Platzierung Konsistenz gehen.)

+1

Was Sie gepostet haben, ist kein gültiges Markup, können Sie ein vollständiges Beispiel geben? –

+0

enthalten die 'td' Elemente entweder' p' Elemente oder keine Elemente? –

+0

@ Nick Craver: Es ist möglicherweise nicht gültig, aber es könnte genau sein, was auf der Seite ist. Trotz der nicht abgeschlossenen "p" -Tags ist die Absicht klar genug. –

Antwort

1

Ja, du jQuery durch die Erweiterung tun.

Diesen in der Nähe der Spitze Ihrer GM-Datei:

$.fn.substituteIfPresent = function (tagName) 
{ 
    return this.map (function() 
    { 
     var childArray = $(this).children (tagName); 

     if (childArray.length) 
      return childArray[0]; 
     else 
      return this; 
    }); 
} 


Dann können Sie das gewünschte Element mit bekommen:

X = $("center > table > tbody > tr > td").substituteIfPresent ('p'); 

//-- Note that X is a standard jQuery object, the following works: 
X.css ('border', '1px solid green'); 


Diese Version von substituteIfPresent() gibt nur die ersten p Tag, falls vorhanden.

+0

Während alle vorgeschlagenen Lösungen im Wesentlichen die gleiche Sache verwenden, die ich bereits mit 'if $ ('p'). length 'mache, macht diese die meisten JQuery-ish für mich. :-) – Hellion

1

Nicht möglich in einzelne jQuery Aussage, aber man kann etwas tun:

var $elem = $('p').length > 0 ? $('p') : $('table'); 

$elem.append(...); 
+0

var $ elem = $ ('p'). Länge? $ ('p'): $ ('Tabelle'); – mkoryak

0

Ein schöner Weg, mit nur einem Selektor Betrieb ist dies:

var $el = (function(){ 
    var $td = $('td'), // you probably want a more precise selector here 
     $p = $td.find('p:last'); 

    return $p.length ? $p : $td; 
})(); 

Dies setzt $el bis zum letzten Element, wenn vorhanden und ansonsten zum td Element. Beachten Sie, dass dies zu unerwarteten Ergebnissen führt, wenn Sie mehr als ein td Element auf Ihrer Seite haben. Verwenden Sie daher einen präziseren Selektor als $('td').

Der Grund für die Selbstausführungsfunktion besteht darin, den Bereich nicht durch zusätzliche Variablen zu verschmutzen.

1

würde ich .map (oder .each) für diesen Einsatz:

$("center > table > tbody > tr > td").map(function() { 
    if($(this).find("p").length) { 
     $(this).find("p").css("border", "1px solid red"); 
    } else { 
     $(this).css("border", "1px solid green"); 
    } 
}); 

Demo: http://jsfiddle.net/tBWhH/3/

+1

Da Sie keinen Wert zurückgeben, wäre es wahrscheinlich sinnvoller, '.each()' zu verwenden. : o) – user113716

+0

@patrick - guter Punkt, aber ich denke, der Effekt ist der gleiche Weg. Ich spielte zunächst mit der Rückgabe einer Sammlung - aber dann verwirrte ich mich etwas. – karim79

+0

Oder verwenden Sie den Rückgabewert, da OP das eine oder andere zu haben scheint. http://jsfiddle.net/tBWhH/4/ – user113716

Verwandte Themen