현재 노드를 포함하는 jQuery find (..) 메소드를 찾고 있습니다.


134

jQuery find (..) 순회 메소드에는 현재 노드가 포함되어 있지 않습니다. 현재 노드의 하위 항목으로 시작합니다. 일치하는 알고리즘에 현재 노드를 포함하는 찾기 작업을 호출하는 가장 좋은 방법은 무엇입니까? 문서를 살펴보면 아무것도 즉시 나에게 튀어 나오지 않습니다.

답변:


153

jQuery 1.8 이상에서는을 사용할 수 있습니다 .addBack(). 선택기가 필요하므로 결과를 필터링하지 않아도됩니다.

object.find('selector').addBack('selector')

jQuery 1.8 이전에는 .andSelf()필터링이 필요한 (이제 더 이상 사용되지 않고 제거되었습니다) 붙어 있습니다 .

object.find('selector').andSelf().filter('selector')

5
나는 이것을 bower에 등록 된 플러그인 jquery.findIncludeSelf로 묶었습니다.
ronen을

18
@ronen 한 줄로 할 수있는 추가 파일이 있습니까? 고맙지 만 괜찮아요.

6
@ prc322 여분의 파일은 모든 자바 스크립트를 단일 파일로 묶는 배포를 방해하지 않습니다. 일반적으로 코드를 읽기가 더 어렵고 버그가 발생할 가능성이 높은 것들로 코드를 복잡하게 만드는 것보다는 단순한 것에서도 테스트 된 라이브러리 방법을 선호합니다. 이 경우 특히 IMHO는 'selector'두 번 지정해야 캡슐화가 더 바람직합니다. YMMV
ronen

좋아, 그래서 나는 두껍게 될 수도 있지만 'selector'두 번 지정할 필요가 없습니다 (@ronen에서 언급했듯이), 그냥 사용할 수 없었 object.parent().find('selector')습니까 ??? — 나는 그것이 당신을 위해 그것을하는 lib의 아이디어를 좋아한다고 말합니다.
Sam

8
@ circa1983 object.parent().find('selector')에는 형제 자매 object와 그 자손이 포함됩니다.
Robert

41

내가 직접 생각할 수없는, 내가 생각할 수있는 가장 가까운 것은 다음과 같이 사용 .andSelf()하고 호출하는 것입니다 .filter().

$(selector).find(oSelector).andSelf().filter(oSelector)
//or...
$(selector).find('*').andSelf().filter(oSelector);

불행히도 .andSelf()선택기를 사용하지 않으므로 편리합니다.


7
당신은이 질문에 대답 한 직후 jquery 페이지에 의견을 추가했습니다 . api.jquery.com/andSelf/#comment-50124533 이제 철저합니다. 좋은! 나는 내 실사를하고 그 일을 '좋아했습니다'.
John K

2
두 번째는 엄청나게 느릴 것입니다. 첫 번째는 단순히 느리다.
Tgr

@Tgr-동의하지는 않지만 매우 많은 수의 요소를 다루지 않는 한 첫 번째 쇼는 아닙니다 . 체인을 연결할 필요가없는 경우 해당 요소를 다시 필터링하지 않아도됩니다.
Nick Craver

3
흥미롭게도 closest(..)현재 DOM 요소와 트리를 포함하는 반면 트리 등의 모든 순회 메소드 find(..)는 현재 요소와 일치하지 않습니다. 마치 jQuery 팀이 두 작업이 모두 세로 검색을 위해 함께 사용될 때 중복되지 않도록 의도적으로 구현 한 것처럼 보입니다.
John K

17
.andSelf ()는 v1.8부터 더 이상 사용되지 않으며 선택자를 인수로 사용하는 .addBack ()으로 대체되었습니다. 참조 api.jquery.com/addBack
kkara

9

밝히다

$.fn.findSelf = function(selector) {
    var result = this.find(selector);
    this.each(function() {
        if ($(this).is(selector)) {
            result.add($(this));
        }
    });
    return result;
};

그런 다음 사용

$.findSelf(selector);

대신에

$find(selector);

슬프게도 jQuery에는이 내장 기능이 없습니다. 수년간의 개발로 정말 이상합니다. .find () 작동 방식으로 인해 AJAX 핸들러가 일부 최상위 요소에 적용되지 않았습니다.


이것은 버그입니다. 그들 중 하나만 일치하더라도 "자기"를 모두 추가합니다 ...-이 버그의 한 가지 이유는 jQuery 메소드라는 이름이 잘못되었습니다.
Robert Siemer

신고하신 버그를 수정하려고했습니다. 지금 제대로 작동합니까?
Dmitriy Sintsov

대부분의 다른 답변 filter()이 거기에 사용 되므로 더 의미가 있습니다.
Robert Siemer

5
$('selector').find('otherSelector').add($('selector').filter('otherSelector'))

$('selector')속도 향상을 위해 변수에 저장할 수 있습니다 . 필요한 경우 사용자 정의 함수를 작성할 수도 있습니다.

$.fn.andFind = function(expr) {
  return this.find(expr).add(this.filter(expr));
};

$('selector').andFind('otherSelector')

이것은 셀렉터로 시작 하는 경우에만 작동 하지만 그렇지 않을 수도 있습니다. 또한 잘못 $('selector').find('otherSelector').add($('otherSelector'))되었습니다 .andSelf(). 현재 가지고있는 것과 같습니다 . 마지막으로, .andFind()표현식을 기반으로 필터링하지 않습니다. .add($(this).filter(expr)):)
Nick Craver

@Nick Craver : 예, 필터링 부분을 잊어 버렸습니다. $('selector')jQuery 객체를 얻는 다른 방법으로 대체 되는지 여부 는 중요하지 않습니다 (선택기로 시작하지 않는 것이 의미가있는 경우) add()가능한 한 모든 것을 처리 $()할 수 있습니다.
Tgr

내 요점은 당신 $('selector')$('selector').children('filter').closest('.class').last()... 체인에있을 수 있으며 추가하는 객체가 무엇인지 전혀 모른다는 것이므로 일반적인 솔루션은 필터처럼 이전 객체를
가져와야합니다.

나는 왜 그것이 문제가 될지 알지 못한다. this플러그인이 호출 된 jQuery 객체입니다. 콜 체인의 결과 일 수도 있습니다.
Tgr

5

허용되는 답변은 매우 비효율적이며 이미 일치하는 요소 집합을 필터링합니다.

//find descendants that match the selector
var $selection = $context.find(selector);
//filter the parent/context based on the selector and add it
$selection = $selection.add($context.filter(selector);

3

체인이 제대로 작동하려면 아래 스 니펫을 사용하십시오.

$.fn.findBack = function(expr) {
    var r = this.find(expr);
    if (this.is(expr)) r = r.add(this);
    return this.pushStack(r);
};

end 함수를 호출 한 후 #foo 요소를 반환합니다.

$('#foo')
    .findBack('.red')
        .css('color', 'red')
    .end()
    .removeAttr('id');

추가 플러그인을 정의하지 않으면이 문제가 발생합니다.

$('#foo')
    .find('.red')
        .addBack('.red')
            .css('color', 'red')
        .end()
    .end()
    .removeAttr('id');

아, 아뇨 ... 만약 this하나 이상의 요소 this.is()만 일치한다면 이미 하나 이상의 요소 가 만족된다면.
Robert Siemer

3

현재 요소 또는 내부의 요소 중 하나정확히 찾고있는 경우 다음 을 사용할 수 있습니다.

result = elem.is(selector) ? elem : elem.find(selector);

여러 요소 를 찾는 경우 다음 을 사용할 수 있습니다.

result = elem.filter(selector).add(elem.find(selector));

andSelf/ 사용 andBack은 매우 드물지만 왜 그런지 확실하지 않습니다. 아마도 성능 문제로 인해 일부 사람들이 앞에서 언급했습니다.

(지금은 Tgr이 이미 두 번째 해결책을 제시했음을 알았습니다 )


2

나는 이것이 오래된 질문이라는 것을 알고 있지만 더 올바른 방법이 있습니다. 예를 들어와 같은 선택기를 일치시킬 때 순서가 중요한 :first경우 find()실제로 현재 요소 집합을 포함하는 것과 동일한 결과를 반환하는 작은 함수를 작성했습니다 .

$.fn.findAll = function(selector) {
  var $result = $();

  for(var i = 0; i < this.length; i++) {
    $result = $result.add(this.eq(i).filter(selector));
    $result = $result.add(this.eq(i).find(selector));
  }

  return $result.filter(selector);
};

어떤 방법으로도 효율적이지는 않지만 적절한 순서를 유지하기 위해 내가 찾은 최고입니다.


1

andSelf당신이 원하는 것 같아요 :

obj.find(selector).andSelf()

선택기와 일치하는지 여부에 관계없이 항상 현재 노드를 다시 추가합니다.


1

현재 노드를 엄격히 찾고 있다면 간단히 수행하십시오.

$(html).filter('selector')

0

나는 스스로 반복하지 않는 솔루션 을 찾으려고 노력했습니다 (즉, 동일한 선택기에 두 번 입력 하지 않음 ).

그리고이 작은 jQuery 확장은 다음을 수행합니다.

jQuery.fn.findWithSelf = function(...args) {
  return this.pushStack(this.find(...args).add(this.filter(...args)));
};

find()(자손 만)과 filter()(현재 세트 만 )을 결합 하고 둘 다 먹는 인수를 모두 지원합니다. 이 pushStack()가능 .end()예상대로 작동합니다.

다음과 같이 사용하십시오.

$(element).findWithSelf('.target')

-2

올바른 (하지만 슬픈) 진실은 다음과 같습니다.

$(selector).parent().find(oSelector).filter($(selector).find('*'))

http://jsfiddle.net/SergeJcqmn/MeQb8/2/


그러나 분리 된 노드 (및 문서 자체)에서는 작동하지 않습니다.
John Dvorak

2
아니, 이것은 $(selector)모든 경우에 세트에서 자신을 제거 합니다.
John Dvorak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.