开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜