Câu trả lời:
Đối với jQuery 1.8 trở lên, bạn có thể sử dụng .addBack()
. Phải mất một bộ chọn để bạn không cần phải lọc kết quả:
object.find('selector').addBack('selector')
Trước jQuery 1.8, bạn đã bị mắc kẹt .andSelf()
, (hiện không dùng nữa và đã bị xóa) mà sau đó cần lọc:
object.find('selector').andSelf().filter('selector')
'selector'
hai lần làm cho việc đóng gói thêm mong muốn. YMMV
'selector'
hai lần, (như được đề cập bởi @ronen), bạn không thể sử dụng object.parent().find('selector')
??? - điều đó được nói rằng tôi thích ý tưởng về một lib làm điều đó cho bạn.
object.parent().find('selector')
bao gồm anh chị em ruột object
và con cháu của họ.
Bạn không thể làm điều này trực tiếp, gần nhất tôi có thể nghĩ đến là sử dụng .andSelf()
và gọi .filter()
, như thế này:
$(selector).find(oSelector).andSelf().filter(oSelector)
//or...
$(selector).find('*').andSelf().filter(oSelector);
Thật không may .andSelf()
, không có một bộ chọn, sẽ rất hữu ích.
closest(..)
bao gồm phần tử DOM hiện tại và lên cây trong khi tất cả các phương thức truyền tải xuống dưới cây như find(..)
vv không khớp với phần tử hiện tại. Như thể nhóm jQuery cố tình thực hiện những điều này để không trùng lặp khi cả hai hoạt động được sử dụng cùng nhau cho một tìm kiếm dọc đầy đủ.
Định nghĩa
$.fn.findSelf = function(selector) {
var result = this.find(selector);
this.each(function() {
if ($(this).is(selector)) {
result.add($(this));
}
});
return result;
};
sau đó sử dụng
$.findSelf(selector);
thay vì
$find(selector);
Đáng buồn là jQuery không tích hợp sẵn. Thực sự kỳ lạ cho rất nhiều năm phát triển. Trình xử lý AJAX của tôi không được áp dụng cho một số phần tử hàng đầu do cách .find () hoạt động.
filter()
ở đó, mà có ý nghĩa hơn.
$('selector').find('otherSelector').add($('selector').filter('otherSelector'))
Bạn có thể lưu trữ $('selector')
trong một biến để tăng tốc. Bạn thậm chí có thể viết một chức năng tùy chỉnh cho việc này nếu bạn cần nó rất nhiều:
$.fn.andFind = function(expr) {
return this.find(expr).add(this.filter(expr));
};
$('selector').andFind('otherSelector')
$('selector').find('otherSelector').add($('otherSelector'))
, những gì bạn có bây giờ tương đương với .andSelf()
. Cuối cùng, .andFind()
bộ lọc không dựa trên biểu thức, bạn sẽ cần .add($(this).filter(expr))
:)
$('selector')
được thay thế bằng một số phương pháp khác để lấy đối tượng jQuery (nếu đó là ý bạn không bắt đầu với bộ chọn), add()
có thể xử lý mọi thứ $()
có thể.
$('selector')
có thể là $('selector').children('filter').closest('.class').last()
... nó có thể nằm trong một chuỗi và bạn không biết đối tượng bạn đang thêm là gì, vì vậy giải pháp chung nên lấy đối tượng trước đó giống như bộ lọc :)
this
là bất cứ đối tượng jQuery nào mà một plugin được gọi. Nó cũng có thể là kết quả của một chuỗi cuộc gọi.
Câu trả lời được chấp nhận là rất không hiệu quả và lọc tập hợp các yếu tố đã được khớp.
//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);
Nếu bạn muốn chuỗi hoạt động đúng, hãy sử dụng đoạn trích dưới đây.
$.fn.findBack = function(expr) {
var r = this.find(expr);
if (this.is(expr)) r = r.add(this);
return this.pushStack(r);
};
Sau khi gọi hàm kết thúc, nó trả về phần tử #foo.
$('#foo')
.findBack('.red')
.css('color', 'red')
.end()
.removeAttr('id');
Không xác định bổ sung, bạn bị mắc kẹt với điều này.
$('#foo')
.find('.red')
.addBack('.red')
.css('color', 'red')
.end()
.end()
.removeAttr('id');
this
có nhiều hơn một yếu tố this.is()
đã được thỏa mãn nếu chỉ một trong số chúng khớp.
Trong trường hợp bạn đang tìm kiếm chính xác một yếu tố , hoặc yếu tố hiện tại hoặc một yếu tố bên trong nó, bạn có thể sử dụng:
result = elem.is(selector) ? elem : elem.find(selector);
Trong trường hợp bạn đang tìm kiếm nhiều yếu tố bạn có thể sử dụng:
result = elem.filter(selector).add(elem.find(selector));
Việc sử dụng andSelf
/ andBack
là khá hiếm, không biết tại sao. Có lẽ vì vấn đề hiệu suất mà một số kẻ đã đề cập trước tôi.
(Bây giờ tôi nhận thấy rằng Tgr đã đưa ra giải pháp thứ hai đó)
Tôi biết đây là một câu hỏi cũ, nhưng có một cách chính xác hơn. Nếu thứ tự là quan trọng, ví dụ như khi bạn khớp với bộ chọn như thế :first
, tôi đã viết lên một hàm nhỏ sẽ trả về kết quả chính xác giống như find()
thực sự bao gồm tập hợp các phần tử hiện tại:
$.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);
};
Nó sẽ không hiệu quả bằng bất kỳ phương tiện nào, nhưng đó là cách tốt nhất tôi nghĩ ra để duy trì trật tự đúng đắn.
Nếu bạn đang nghiêm túc tìm kiếm trong (các) nút hiện tại, bạn chỉ cần làm
$(html).filter('selector')
Tôi đã cố gắng tìm một giải pháp không lặp lại (nghĩa là không nhập cùng một bộ chọn hai lần).
Và phần mở rộng jQuery nhỏ này thực hiện điều đó:
jQuery.fn.findWithSelf = function(...args) {
return this.pushStack(this.find(...args).add(this.filter(...args)));
};
Nó kết hợp find()
(chỉ con cháu) với filter()
(chỉ bộ hiện tại) và hỗ trợ bất kỳ đối số nào cả hai ăn. Các pushStack()
cho phép .end()
làm việc như mong đợi.
Sử dụng như thế này:
$(element).findWithSelf('.target')
Đây là sự thật đúng (nhưng buồn):
$(selector).parent().find(oSelector).filter($(selector).find('*'))
$(selector)
tự xóa khỏi tập hợp trong mọi trường hợp.