Jquery: idiomatic way to select element A if present, element B otherwise?
I'm writing a GreaseMonkey script with JQuery.
Sometimes the site I want to modify displays information in a TD, thus:<center><table><tr><td>
Something interesting here.</td></tr>....</table开发者_StackOverflow中文版></center>
whereas sometimes it displays things in a P tag (or several) within the same table structure, thus:
<center><table><tr><td>
<p>Other text about the same interesting thing.
<p>and maybe some more stuff too.</td></tr>...</table></center>
Right now I'm doing two different selectors to select the <p>
vs. the <td>
, but I'm wondering if there's a nice way to select only the P tag if it's present and the TD otherwise in a single Jquery selector, since what I want to append is identical in both cases.
(If I just append to the TD regardless, the location of my addition changes based on the presence/absence of the P tag, so I'm going for placement consistency.)
Yes, You can do this by extending jQuery.
Put this near the top of your GM file:
$.fn.substituteIfPresent = function (tagName)
{
return this.map (function ()
{
var childArray = $(this).children (tagName);
if (childArray.length)
return childArray[0];
else
return this;
});
}
Then you can get the desired element with:
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');
This version of substituteIfPresent()
returns only the first p
tag, if present.
Not possible in single jQuery statement, but you can do something like this:
var $elem = $('p').length > 0 ? $('p') : $('table');
$elem.append(...);
I would use .map
(or .each
) for this:
$("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/
A nice way with only one selector operation is this:
var $el = (function(){
var $td = $('td'), // you probably want a more precise selector here
$p = $td.find('p:last');
return $p.length ? $p : $td;
})();
This sets $el
to the last p
element if any exist and otherwise to the td
element. Note that this will have unexpected results if you have more than one td
element on your page, so you should use a more precise selector than $('td')
.
The reason for the self-executing function is to avoid polluting your scope with extra variables.
精彩评论