jQuery .close()와 비슷하지만 후손을 횡단합니까?
와 비슷한 기능이 있습니까?jQuery
.closest()
하지만 가장 가까운 자손만 돌아오는 것에 대해서는?
나는 그것이 있다는 것을 압니다..find()
function, 그러나 가능한 모든 일치를 반환합니다. 근접하지 않습니다.
편집:
다음은 (적어도 나에게는) 가장 가까운 것에 대한 정의입니다.
처음에는 모든 어린이가 횡단하고, 그 다음에는 각 어린이가 횡단합니다.
아래에 주어진 예에서id='2'
가장 가깝습니다.closest
의 자손.id="find-my-closest-descendant"
<div id="find-my-closest-descendant">
<div>
<div class="closest" Id='1'></div>
</div>
<div class="closest" Id='2'></div>
</div>
Jsfiddle 링크를 참조해주세요.
"가장 가까운" 자손이 첫째 자녀를 의미하는 경우 다음을 수행할 수 있습니다.
$('#foo').find(':first');
또는:
$('#foo').children().first();
또는 특정 요소가 처음으로 발생하는 경우 다음 작업을 수행할 수 있습니다.
$('#foo').find('.whatever').first();
또는:
$('#foo').find('.whatever:first');
하지만 우리는 "가장 가까운 후손"이 무엇을 의미하는지 확실한 정의가 필요합니다.
예.
<div id="foo">
<p>
<span></span>
</p>
<span></span>
</div>
어떤.<span>
그럴 것이다$('#foo').closestDescendent('span')
돌아오십니까?
당신의 정의에 따르면closest
, 다음 플러그인을 작성했습니다.
(function($) {
$.fn.closest_descendent = function(filter) {
var $found = $(),
$currentSet = this; // Current place
while ($currentSet.length) {
$found = $currentSet.filter(filter);
if ($found.length) break; // At least one match: break loop
// Get all children of the current set
$currentSet = $currentSet.children();
}
return $found.first(); // Return first match of the collection
}
})(jQuery);
사용가능find
와 함께:first
선택기:
$('#parent').find('p:first');
위의 선은 첫 번째 선을 찾을 것입니다.<p>
의 자손에 있는 요소#parent
.
이 방법은 어떻습니까?
$('find-my-closest-descendant').find('> div');
이 "직접 아이" 선택자는 저에게 적합합니다.
(jQuery 대신 ES6를 사용하는) 순수 JS 솔루션을 찾고 있는 사람이 있을 경우, 다음은 제가 사용하는 솔루션입니다.
Element.prototype.QuerySelector_BreadthFirst = function(selector) {
let currentLayerElements = [...this.childNodes];
while (currentLayerElements.length) {
let firstMatchInLayer = currentLayerElements.find(a=>a.matches && a.matches(selector));
if (firstMatchInLayer) return firstMatchInLayer;
currentLayerElements = currentLayerElements.reduce((acc, item)=>acc.concat([...item.childNodes]), []);
}
return null;
};
저는 가장 가까운 것이 무엇을 의미하는지 먼저 정의해야 한다고 생각합니다.상위 링크 측면에서 가장 짧은 거리에 있는 기준과 일치하는 하위 노드를 의미하는 경우 ":first" 또는 ".eq(0)"을 사용해도 작동하지 않습니다.
<div id='start'>
<div>
<div>
<span class='target'></span>
</div>
</div>
<div>
<span class='target'></span>
</div>
</div>
이 예제에서 두 번째 ".target"<span>
요소는 "closer"에서 "시작"입니다.<div>
, 부모님들과 한 번 밖에 떨어져 있지 않기 때문입니다.그것이 "가까운"을 의미하는 것이라면, 필터 함수에서 최소 거리를 찾아야 할 것입니다.jQuery Selector의 결과 목록은 항상 DOM 순서로 표시됩니다.
아마도:
$.fn.closestDescendant = function(sel) {
var rv = $();
this.each(function() {
var base = this, $base = $(base), $found = $base.find(sel);
var dist = null, closest = null;
$found.each(function() {
var $parents = $(this).parents();
for (var i = 0; i < $parents.length; ++i)
if ($parents.get(i) === base) break;
if (dist === null || i < dist) {
dist = i;
closest = this;
}
});
rv.add(closest);
});
return rv;
};
결과 개체를 구축하는 방식 때문에 일종의 해킹 플러그인이지만, 일치하는 모든 요소 중에서 가장 짧은 부모 경로를 찾아야 한다는 생각입니다.이 코드는 DOM 트리에서 왼쪽으로 요소를 편향합니다.<
체크;<=
오른쪽으로 치우칠 겁니다
제가 이것을 조작했습니다. 위치 선정자를 위한 구현은 없습니다(그들은 단지 그 이상의 것이 필요합니다).matchesSelector
) 아직:
데모: http://jsfiddle.net/TL4Bq/3/
(function ($) {
var matchesSelector = jQuery.find.matchesSelector;
$.fn.closestDescendant = function (selector) {
var queue, open, cur, ret = [];
this.each(function () {
queue = [this];
open = [];
while (queue.length) {
cur = queue.shift();
if (!cur || cur.nodeType !== 1) {
continue;
}
if (matchesSelector(cur, selector)) {
ret.push(cur);
return;
}
open.unshift.apply(open, $(cur).children().toArray());
if (!queue.length) {
queue.unshift.apply(queue, open);
open = [];
}
}
});
ret = ret.length > 1 ? jQuery.unique(ret) : ret;
return this.pushStack(ret, "closestDescendant", selector);
};
})(jQuery);
아마 버그가 있을 거예요, 별로 테스트를 안 해봤어요.
롭 W의 대답은 제게 잘 맞지 않았습니다.나는 이것에 적응해서 효과가 있었습니다.
//closest_descendent plugin
$.fn.closest_descendent = function(filter) {
var found = [];
//go through every matched element that is a child of the target element
$(this).find(filter).each(function(){
//when a match is found, add it to the list
found.push($(this));
});
return found[0]; // Return first match in the list
}
셀렉터와 일치하는 경우 대상 자체를 포함하기 위해 다음을 사용합니다.
var jTarget = $("#doo");
var sel = '.pou';
var jDom = jTarget.find(sel).addBack(sel).first();
마크업:
<div id="doo" class="pou">
poo
<div class="foo">foo</div>
<div class="pou">pooo</div>
</div>
다음 플러그인은 n번째로 가까운 하위 항목을 반환합니다.
$.fn.getNthClosestDescendants = function(n, type) {
var closestMatches = [];
var children = this.children();
recursiveMatch(children);
function recursiveMatch(children) {
var matches = children.filter(type);
if (
matches.length &&
closestMatches.length < n
) {
var neededMatches = n - closestMatches.length;
var matchesToAdd = matches.slice(0, neededMatches);
matchesToAdd.each(function() {
closestMatches.push(this);
});
}
if (closestMatches.length < n) {
var newChildren = children.children();
recursiveMatch(newChildren);
}
}
return closestMatches;
};
유사한 솔루션을 찾고 있었습니다(예: 너비 우선 + 수준에 관계없이 모든 가장 가까운 하위 항목을 원합니다).
var item = $('#find-my-closest-descendant');
item.find(".matching-descendant").filter(function () {
var $this = $(this);
return $this.parent().closest("#find-my-closest-descendant").is(item);
}).each(function () {
// Do what you want here
});
도움이 되었으면 좋겠습니다.
순수 JS 용액(ES6 사용).
export function closestDescendant(root, selector) {
const elements = [root];
let e;
do { e = elements.shift(); } while (!e.matches(selector) && elements.push(...e.children));
return e.matches(selector) ? e : null;
}
예
다음 구조를 고려하면 다음과 같습니다.
div == $0├── div == $1│ ├ -- 디브│ ├- div. find me == $4│ ├ -- 디브│ └ -- 디브├── div.find me == $2│ ├ -- 디브│ └ -- 디브└── div == $3├── 디브├── 디브└── 디브
closestDescendant($0, '.findme') === $2;
closestDescendant($1, '.findme') === $4;
closestDescendant($2, '.findme') === $2;
closestDescendant($3, '.findme') === null;
function closestDescendant(root, selector) {
const elements = [root];
let e;
do { e = elements.shift(); } while (!e.matches(selector) && elements.push(...e.children));
return e.matches(selector) ? e : null;
}
const [$0, $1, $2, $3, $4] = [0, 1, 2, 3, 4].map(x => document.querySelector(`#e${x}`));
console.log(closestDescendant($0, '.findme')); // $2
console.log(closestDescendant($1, '.findme')); // $4
console.log(closestDescendant($2, '.findme')); // $2
console.log(closestDescendant($3, '.findme')); // null
<div id="e0">
<div id="e1">
<div></div>
<div id="e4" class="findme"></div>
<div></div>
<div></div>
</div>
<div id="e2" class="findme">
<div></div>
<div></div>
</div>
<div id="e3">
<div></div>
<div></div>
<div></div>
</div>
</div>
비록 오래된 주제이지만, 저는 가장 가까운 차일드를 실행하는 것을 참을 수 없었습니다.이동이 가장 적은 첫 번째 발견된 하위 항목을 전달합니다(숨을 먼저 쉬십시오).하나는 재귀적(personal favorite)이고, 다른 하나는 todo 목록을 사용하여 jQquery 확장자로 재귀하지 않습니다.
누군가가 혜택을 받았으면 좋겠습니다.
참고 : 재귀적인 것은 스택 오버플로를 가져오며, 다른 것은 이전의 답변과 유사하게 개선했습니다.
jQuery.fn.extend( {
closestChild_err : function( selector ) { // recursive, stack overflow when not found
var found = this.children( selector ).first();
if ( found.length == 0 ) {
found = this.children().closestChild( selector ).first(); // check all children
}
return found;
},
closestChild : function( selector ) {
var todo = this.children(); // start whith children, excluding this
while ( todo.length > 0 ) {
var found = todo.filter( selector );
if ( found.length > 0 ) { // found closest: happy
return found.first();
} else {
todo = todo.children();
}
}
return $();
},
});
그냥 간단하게 말하면 됩니다.
$("#find-my-closest-descendant").siblings('.closest:first');
OP가 요구하는 것을 가장 가까운 [Geeks for Geeks]로 쉽게 달성할 수 있다는 훌륭한 기사가 있습니다.
1
하지만 당신은 많은 선택권이 있습니다.$("#parent").children(".child");
패스트릿입니다.자세한 사항과 벤치마크를 위해 이 기사를 확인합니다.
언급URL : https://stackoverflow.com/questions/8961770/similar-to-jquery-closest-but-traversing-descendants
'programing' 카테고리의 다른 글
문자열을 대문자로 분할 (0) | 2023.10.22 |
---|---|
JVM 프로세스는 메모리를 어떻게 할당합니까? (0) | 2023.10.22 |
PL/MySQL이 존재합니까? (0) | 2023.10.22 |
C에서 주(공)와 주()의 차이 (0) | 2023.10.22 |
MySQL에서 두 날짜 간의 연도 차이를 정수로 가져옵니다. (0) | 2023.10.22 |