12

私は次のようなネストされたテーブル構造を持っています

   <table>

       <td id="first">

           <div class="wrapper">
               <input name=1>
           </div>

           <input name=2>

           <table>

               <td id="second">

                   <input name=3>

jQueryの選択があり$("#first")ます。このコンテキスト内でfind()すべての子をトラバースしたいのですが、ネストされたsに降下したくありません。<input>s<td><table>

だから私はjQueryのトリックが必要です

  • 特定find()の要素のすべての子要素

  • DOMツリーでnレベル下がる

  • ただし、特定の要素()が検出されると下降が停止する<table>ため、セレクターはネストされたテーブルの入力を選択しません(個別に処理されます)。

  • ネストされたレベルはいくつでも存在する可能性があるため、 $( "#first")またはその他のスコープ内で検出された親または子の数に<table>関係なく、ソリューションは機能するはずです。<table><table><td><td>

質問があるまで他のjQuery検索をチェックしました。彼らには答えがありますが、最後の基準を満たしていないようです

4

4 に答える 4

5

この他の質問でも同様の問題がありました。検索セレクターについて考えようとしている人たちと行ったり来たりした後、私はついに自分でプラグインを見つけました。

利用方法 : ExclusiveInputs = $('#first').findExclude('input','table');

// Find-like method which masks any descendant
// branches matching the Mask argument.
$.fn.findExclude = function( Selector, Mask, result){

    // Default result to an empty jQuery object if not provided
    var result = typeof result !== 'undefined' ?
                result :
                new jQuery();

    // Iterate through all children, except those match Mask
    this.children().each(function(){

        var thisObject = jQuery( this );
        if( thisObject.is( Selector ) ) 
            result.push( this );

        // Recursively seek children without Mask
        if( !thisObject.is( Mask ) )
            thisObject.findExclude( Selector, Mask, result );
    });

    return result;
}

(要約版)

$.fn.findExclude = function( selector, mask, result )
{
    var result = typeof result !== 'undefined' ? result : new jQuery();
    this.children().each( function(){
        var thisObject = jQuery( this );
        if( thisObject.is( selector ) ) 
            result.push( this );
        if( !thisObject.is( mask ) )
            thisObject.findExclude( selector, mask, result );
    });
    return result;
}
于 2014-06-16T19:00:25.973 に答える
3

更新:これについて別の見方をしましょう。

<input>基本的に、の子孫であり、の1レベル以上下にネストされた要素#firstの子ではないすべての要素を一致させる必要があります。<td>#first

(その最後の部分についてはわかりませんが、それを実装することで、祖先チェーンの上記の要素under #firstをサポートできます。)<td>#first

技術的には、次のセレクターだけで要件を満たす必要があります。

var inputs = $("#first td:not(#first td td) > input");

これがブラウザで機能しない場合(Sizzleは私が思うタスクに任せる必要がありますが、のような複雑なセレクター:not()は常に注意が必要です)、処理をjQueryメソッドに委任できます。

var inputs = $("#first td").not("#first td td").children("input");

元の答えは次のとおりです。

not()を使用<input>して、複数の<td>祖先を持つ要素を除外できます。

var firstLevelCells = $("#first").find("input").not("td td input");
于 2012-11-09T10:01:42.803 に答える
2

ええ、私はより良い考えを持っています。

var badTable = "table.bad"; //the one you want to avoid
var $goodInputs = $("#first").find('input').filter(function() {
    return $(this).closest(badTable).length == 0;
});

これはあなたにとって十分に速いかもしれないし、そうでないかもしれません。それはあなたが話したくないあなたのDOMに依存します;)

遅い場合は、アルゴリズムのコードを手作業で記述してください。セレクターショートカットはありません。

于 2012-11-09T09:45:28.227 に答える
1

私も同様の問題を抱えていましたが、拡張ループを使用せずに、またはDOMの正確な構造を使用して何かを実行するという課題がありました。私の場合、私はすでに要素'#first'への参照を持っていました。そうでない場合は、たとえば、それぞれで取得できます(オブジェクトが1つしかない場合でも)。秘訣は、親と一緒にツリーに戻り、最上位の要素で停止して、条件を満たす中間要素があるかどうかを確認することです。

関数に省略形のラムダ表記を使用すると(typescriptで記述できるように)、これは次のようになります。

$('#first').each((idx, f) => $(f).find('input').filter((idx2, inp) => $(inp).parentsUntil(f, 'table').length == 0)

これは最も効率的な方法ではない可能性があります(最初にすべてを選択してから、DOMツリーを再度マウントして要素を破棄するためですが、コンパクトでかなり一般的です。

于 2016-07-05T09:30:27.780 に答える