7

この例を考えると:

<img class="a" />
<img />
<img class="a" />
<img class="a" id="active" />
<img class="a" />
<img class="a" />
<img />
<img class="a" />

(私は例として img タグを使用しましたが、それは私のコードではありません)

jQuery を使用して、#active に隣接するクラス "a" の img タグ (この例では中央の 4 つ) をどのように選択しますか?

前後のすべての要素をループして、フィルター条件が失敗したときに停止することで、かなり簡単に実行できますが、jQuery でネイティブに実行できるかどうか疑問に思っていました。

4

6 に答える 6

4

これが私が最終的に思いついたものです。

// here's our active element.
var $active = $('#active');

// here is the filter we'll be testing against.
var filter = "img.a";

// $all will be the final jQuery object with all the consecutively matched elements.
// start it out by populating it with the current object.
var $all = $active;

for ($curr = $active.prev(filter); $curr.length > 0; $curr = $curr.prev(filter)) {
    $all = $all.add($curr);
}
for ($curr = $td.next(filter); $curr.length > 0; $curr = $curr.next(filter)) {
    $all = $all.add($curr);
}

フォローアップの質問については、初期要素とフィルター文字列の2つの引数を取る関数にすることで、これを簡単に一般化できることがわかりました。誰でも正しい方向に向けて、拡張する方法を見つけることができます。そのような関数を追加するjQueryオブジェクト?


編集:それ以来、each()関数がいくつかの目的のためにこれをかなりうまく行うことを発見しました。私自身の場合、これらすべての要素に対して単一のjQueryオブジェクトが必要なため、うまく機能しませんが、それぞれを異なる目的で使用する方法を次に示します(この例では、連続する「.a」要素を非表示にします:)

$('#active')
    .nextAll()
    .each(hideConsecutive)
    .end()
    .prevAll()
    .each(hideConsecutive)
;
function hideConsecutive(index, element) {
    var $e = $(element);
    if (!$e.is(".a")) {
        return false;    // this stops the each function.
    } else {
        $e.hide('slow');
    }
}

-

編集:これをプラグインにまとめました。興味がある場合は、http://plugins.jquery.com/project/Adjacentをご覧ください。

于 2008-09-17T05:30:03.387 に答える
2

ループが最善の策だと思います。ただし、それぞれをアクティブにしてから、条件が壊れるまで前後に移動することもできます。セットが十分に大きい場合は、より高速になります。

于 2008-09-17T02:55:32.853 に答える
1

以下のコードは、nextConsecutive() と prevConsecutive() という 2 つの新しい関数を追加します。彼らはあなたが望むことをするべきです。

$.each( ['prev', 'next'], function(unusedIndex, name) { $.fn[ name + 'Consecutive' ] = function(matchExpr) {

    var $all = 
        (name == 'prev')
             ? $(this).prevAll()
             : $(this).nextAll();
    if (!matchExpr)
        return $all;

    var $notMatch = $($all).not(matchExpr).filter(':first');
    if ($all.index($notMatch) != -1)
        return $allConsecutive = $all.slice(0, $all.index($notMatch));

    return $all;
};

});

于 2009-04-18T14:07:15.703 に答える
0

これは別の方法ですが、兄弟セレクターの答えはかなりクールです。

var next = $('#active').next('.a');
var prev = $('#active').prev('.a');

編集:私はあなたの要件を読み直しました、そしてこれはあなたが望むものではありません。nextAllとprevAllを使用することもできますが、それらもクラス名がないとIMGで停止しません。

于 2008-09-17T04:26:46.003 に答える
0

@Prestaul

$('#active ~ img.a')

の兄弟のみを選択し、連続していない兄弟も含めます。ドキュメント:http ://docs.jquery.com/Selectors/siblings#prevsiblings

于 2008-09-17T04:04:13.013 に答える
0

チルダ (~) は兄弟セレクターです:

$('#active ~ img.a').hide();
于 2008-09-17T03:48:26.547 に答える