JQuery: идиоматический способ выбора элемента A, если присутствует, элемент B в противном случае - PullRequest
3 голосов
/ 18 ноября 2010

Я пишу сценарий GreaseMonkey с JQuery.
Иногда сайт, который я хочу изменить, отображает информацию в ТД, таким образом:

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

тогда как иногда он отображает вещи в теге P (или нескольких) в одной и той же структуре таблицы, таким образом:

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

Сейчас я делаю два разных селектора, чтобы выбрать <p> вместо <td>, но мне интересно, есть ли хороший способ выбрать только тег P, если он присутствует, и TD в противном случае в один селектор Jquery, поскольку то, что я хочу добавить, идентично в обоих случаях.

(Если я просто добавлю к TD, местоположение моего добавления изменится в зависимости от наличия / отсутствия тега P, поэтому я собираюсь обеспечить согласованность размещения.)

Ответы [ 4 ]

1 голос
/ 18 ноября 2010

Да, вы можете сделать это, расширив jQuery.

Поместите это в верхнюю часть вашего файла GM:

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

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


Тогда вы можете получить нужный элемент с помощью:

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');


Эта версия substituteIfPresent() возвращает только первый тег p, если имеется.

1 голос
/ 18 ноября 2010

Я бы использовал .map (или .each) для этого:

$("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");
    } 
});

Демонстрация: http://jsfiddle.net/tBWhH/3/

1 голос
/ 18 ноября 2010

Невозможно в одном выражении jQuery, но вы можете сделать что-то вроде этого:

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

$elem.append(...);
0 голосов
/ 18 ноября 2010

Хороший способ только с одной операцией выбора заключается в следующем:

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

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

Это устанавливает $el на последний элемент p, если таковой существует, а в противном случае на элемент td.Обратите внимание, что это приведет к неожиданным результатам, если у вас будет более одного элемента td на вашей странице, поэтому вам следует использовать более точный селектор, чем $('td').

. Причина для самореализующейся функции заключается вИзбегайте загрязнения вашей области видимости дополнительными переменными.

...