JQuery селектор логический И? - PullRequest
1 голос
/ 27 мая 2010

В jQuery я пытаюсь выбрать только те узлы монтирования, где текстовые значения a и b равны 64 и «тестируются» соответственно. Я также хотел бы вернуться к 32, если нет 64 и «тест» существует. Что я вижу в приведенном ниже коде, так это то, что монтирование 32 возвращается вместо 64.

XML:


<thingses>
    <thing>
        <a>32</a> <-- note, a here is 32 and not 64 -->
        <other>...</other>
        <mount>sample 1</mount>
        <b>test</b>
    </thing>
    <thing>
        <a>64</a>
        <other>...</other>
        <mount>sample 2</mount>
        <b>test</b>
    </thing>
    <thing>
        <a>64</a>
        <other>...</other>
        <mount>sample 3</mount>
        <b>unrelated</b>
    </thing>
    <thing>
        <a>128</a>
        <other>...</other>
        <mount>sample 4</mount>
        <b>unrelated</b>
    </thing>
</thingses>

И, к сожалению, я не могу контролировать XML, поскольку он откуда-то еще.

То, что я сейчас делаю, это:


var ret_val = '';

$data.find('thingses thing').each(function(i, node) {
    var $node = $(node), found_node = $node.find('b:first:is(test), a:first:is(64)').end().find('mount:first').text();
    if(found_node) {
        ret_val = found_node;
        return;
    }

    found_node = $node.find('b:first:is(test), a:first:is(32)').end().find('mount:first').text();
    if(found_node) {
        ret_val = found_node;
        return;
    }

    ret_val = 'not found';
});

// expected result is "sample 2", but if sample 2's parent "thing" was missing, the result would be "sample 1"
alert(ret_val);

Для моего селектора ": is" я использую:


    if(jQuery){
        jQuery.expr[":"].is = function(obj, index, meta, stack){
            return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
        };
    }

Должен быть лучший способ, чем то, как я это делаю. Я хотел бы заменить "," на "И" или что-то в этом роде. :)

Любая помощь будет высоко ценится. спасибо!

Ответы [ 3 ]

0 голосов
/ 27 мая 2010

Мне кажется, это работает:

var el = $('thingses thing')
    .has('b:contains("test")')
    .has('a:contains(64)');
if(!el.length) 
    el = $('thingses thing')
        .has('b:contains("test")')
        .has('a:contains(32)');
alert(el.find('mount:first').text());
0 голосов
/ 27 мая 2010

Различные идеи:

  • Использование родственного селектора ( Иерархические селекторы в jQuery )
    b может предшествовать или следовать за a, в противном случае вы можете оставить половину селектора

    find ('b: first: is (test) ~ a: first: is (64), a: first: is (64) ~ b: first: is (test)')

  • найди одну, вернись и найди другую. Я думаю, что это может быть некрасиво, хотя

    находка ( 'б: первый: есть (тест)) родитель () найти.. (' А: первый: есть (64) ')

  • пользовательские селекторы jQuery могут принимать параметры, поэтому вы можете написать свой: allAtOnce selector:)

0 голосов
/ 27 мая 2010

Почему вы звоните end() после find()? Возможно, я неправильно понимаю ваше намерение, но end() возвращает вас к $node, так что последующее find("mount:first") просто возвращает вам первого mount ребенка этого.

Я здесь не прав?

Редактировать

Кроме того, почему вы делаете .each на всех thing с? Таким образом, ваш ret_value фактически получит mount значение last thing, которое соответствует условию 64-if-not-then-32 .

Если вы хотите выбрать первый 64 / test thing, а если такого нет, то первый 32 / test , тогда почему бы вам просто написать это явно?

var ret_value = $data.find( "thingses > thing:has( a:is(64) ):has( b:is(test) ) > mount" ).text();
if ( !ret_value )
    ret_value = $data.find( "thingses > thing:has( a:is(32) ):has( b:is(test) ) > mount" ).text();

И вы можете инкапсулировать этот длинный запрос, чтобы сделать код более читабельным:

function findByAandB( data, a, b ) {
    return data.find( "thingses > thing:has( a:is(" + a + ") ):has( b:is(" + b + ") ) > mount" ).text();
}

var ret_value = findByAandB( 64, "test" ) || findByAandB( 32, "test" );

Я неправильно понимаю, что вам нужно? Потому что я немного растерялся: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...