4

親チェーンの外側の要素を横方向にトラバースして返すclosest()に似たjQuery関数はありますか?たとえば、divターゲットを返す関数foo()をdivソースで呼び出したいと思います。parent()とsiblings()を使用してナビゲートできることは知っていますが、必要なだけ上、横、下に移動する汎用的なものが必要ですか?

var allsources = $('.source');

allsources.click(function()){
  $(this).closest('.target').hide();
});

<div class="row">
  <div>
     <div class="target" ></div>
  </div>
  <div>
    <div>
      <div class="source"></div>
    </div>
  </div>
</div>

<div class="row">
  <div>
     <div class="target" ></div>
  </div>
  <div>
    <div>
      <div class="source"></div>
    </div>
  </div>
</div>

編集:

私の最も近い定義:あなたは要素ソースを持っています。それを見つけてみてください。複数見つかった場合は、ノードフープダウン/次/前の数が少ないものを返します。見つからない場合は、1つ上のレベルに移動して、もう一度検索してみてください。親がなくなるまで繰り返します。

4

7 に答える 7

7

最も近いとは、「できるだけ上に移動し、次に下に移動する」ことを意味する場合、次のことができます

$("#source")
  .closest(":has(.target)")
  .find(".target:first")  //make sure we only select one element in case of a tie

あなたの場合、共通の親を直接指定する方が良いでしょう:

$(this)
  .closest(".row")
  .find(".target")        //there's no tie here, no need to arbitrate
于 2012-11-30T09:17:23.993 に答える
2

これはトリッキーです。コメントされているように、このコンテキストで最も近いとはどのように定義しますか? いくつかのルールを決定できると仮定します。例えば:

上にトラバース:3pt
下にトラバース:2pts
横に移動:1pts

そして、ポイントが最も低いアイテムを「最も近い」と見なすと、closestAlldom ツリー全体を再帰的に走査して最も近いアイテムを決定する などの名前のプラグインを簡単に作成できます。

ただし、最近の編集を見ると、(多くの!)問題に対する適切な解決策の 1 つが次のように示されています。

var allsources = $('.source');

allsources.click(function(){
  $(this).parents('.row').find('.target').hide();
});

実際の例: http://jsfiddle.net/zCvJM/ (ソース A はターゲット A のみを隠し、B も同じ)

于 2012-11-30T09:19:15.660 に答える
2

DOM の構造とネストのレベルが正確にわかっている場合は、eq() メソッドの使用を検討してください。

$(this).parents().eq(1).prev().children(".target")
于 2012-11-30T09:49:10.707 に答える
1

仕様を正しく理解していれば、以下で定義されている最も近い関数のようなものを意味します。

var allsources = $(".source");

function closest($source,selector) {
    if($source == null) return  $([]);
    var $matchingChildren = $source.find(selector);
    if($matchingChildren.length != 0) return $($matchingChildren.get(0));
    else return closest($source.parent(), selector)
}

allsources.click(closest($(this),'.target').hide();});

http://jsfiddle.net/y2wJV/1/で動作しているのを見ることができます

あなたの定義では、一致する子の中から選択するときに、関数はノード フープ ダウン/ネクスト/プレブが少ないものを返す必要があります。この要件は満たされていませんが、この関数は非常に柔軟で、提供した例の場合にやりたいことを行うようです。

于 2012-11-30T10:40:51.593 に答える
1

基本的にDOM全体をクエリする以外にこれを行う方法はないと思います:

$('#target')

上下に移動したい場合(気にしないでください)、ターゲット要素は子要素に関連していないためです。子要素の存在も確認したい場合は、個別に行う必要があります。

-編集:

親であるかどうかに関係なく、最も近い要素を見つけたいというあなたのコメントを読んだ後、一度に 1 つのノードで dom をクロールするカスタム関数を作成する必要があると思います。私は以下をテストしましたが、動作します:

マークアップ

<div id="parent">
    <div id="child1">   
        <div id="source"></div>
    </div>
    <div id="child2">
        <div class="target" rel="right"></div>
    </div>
    <div id="child3">
        <div>
            <div class="target" rel="wrong"></div>
        </div>
    </div>
</div>

脚本

$(document).ready(function () {
    var tgt = findClosest($('#source'), '.target');
    if (tgt != undefined) {
        alert(tgt.attr('rel'));
    }
});


function findClosest(source, targetSel) {
    var crawledNodes = $();
    var target = null;

    // Go up
    source.parents().each(function () {
        console.log(crawledNodes.index($(this)));
        if (crawledNodes.index($(this)) == -1 && target == null) {
            crawledNodes.add($(this));
            target = findTarget($(this), targetSel);

            // Go across
            $(this).siblings().each(function () {
                console.log("Sibling");
                if (crawledNodes.index($(this)) == -1 && target == null) {
                    crawledNodes.add($(this));
                    target = findTarget($(this), targetSel);
                }
            });
        }
    });

    return target;
}

function findTarget(el, targetSel) {
    console.log(targetSel);
    var target = el.find(targetSel);
    if (target.size() > 0) {
        return target.eq(0);
    }
    else 
    {
        return null;
    }
}
于 2012-11-30T09:08:04.650 に答える
0

同様の問題が発生しました。現在の td の外側にある可能性のある次の要素を見つけるために必要なテーブルがあったため、jquery 関数を作成しました。

    $.fn.nextAllLevels = function(sel) {
    if ($(this).nextAll(sel).length != 0) {
        return $(this).nextAll(sel).eq(0);
    } else if ($(this).nextAll(':has(' +  sel + ')').length != 0) {
        return $(this).nextAll(':has(' +  sel + ')').find(sel).eq(0);
    } else {
        return $(this).parent().nextAllLevels(sel);
    }

したがって、これを使用するには、単に呼び出します

$('#current').nextAllLevels('.target');

in が現在の親にあるかどうかに関係なく、順方向に最も近い要素を提供します。

于 2016-09-20T08:24:06.310 に答える
0

シンプルですが、引き分けの問題を解決しないこのコードを見つけました(最初を返します)...

(function ($) {
  $.fn.findClosest = function (filter) {
    var $found = $(),
            $currentSet = this; // Current place

    while ($currentSet.length) {
        $found = $currentSet.find(filter);
        if ($found.length) break; // At least one match: break loop
        // Get all children of the current set
        $currentSet = $currentSet.parent();
    }
    return $found.first(); // Return first match of the collection
  };
})(jQuery);
于 2012-11-30T10:42:52.400 に答える