วิธีการข้ามผ่านjQuery find (.. )ไม่รวมโหนดปัจจุบัน - เริ่มต้นด้วยลูกของโหนดปัจจุบัน วิธีใดที่ดีที่สุดในการเรียกการดำเนินการค้นหาที่มีโหนดปัจจุบันในอัลกอริทึมการจับคู่ เมื่อมองผ่านเอกสารไม่มีอะไรกระโดดมาที่ฉันทันที
วิธีการข้ามผ่านjQuery find (.. )ไม่รวมโหนดปัจจุบัน - เริ่มต้นด้วยลูกของโหนดปัจจุบัน วิธีใดที่ดีที่สุดในการเรียกการดำเนินการค้นหาที่มีโหนดปัจจุบันในอัลกอริทึมการจับคู่ เมื่อมองผ่านเอกสารไม่มีอะไรกระโดดมาที่ฉันทันที
คำตอบ:
สำหรับ jQuery 1.8 ขึ้นไปคุณสามารถใช้.addBack()
ไฟล์. ต้องใช้ตัวเลือกดังนั้นคุณจึงไม่จำเป็นต้องกรองผลลัพธ์:
object.find('selector').addBack('selector')
ก่อนหน้า jQuery 1.8 คุณติดอยู่.andSelf()
(ตอนนี้เลิกใช้งานและลบออกแล้ว) ซึ่งจำเป็นต้องมีการกรอง:
object.find('selector').andSelf().filter('selector')
'selector'
สองครั้งทำให้การห่อหุ้มเป็นที่ต้องการมากขึ้น YMMV
'selector'
สองครั้ง (ตามที่ @ronen กล่าวไว้) ใช้ไม่ได้เหรอobject.parent().find('selector')
??? - อย่างที่บอกว่าฉันชอบไอเดียของ lib ที่ทำเพื่อคุณ
object.parent().find('selector')
รวมถึงพี่น้องobject
และลูกหลานของพวกเขา
คุณไม่สามารถทำสิ่งนี้ได้โดยตรงสิ่งที่ใกล้เคียงที่สุดที่ฉันคิดได้คือการใช้.andSelf()
และการโทร.filter()
เช่นนี้:
$(selector).find(oSelector).andSelf().filter(oSelector)
//or...
$(selector).find('*').andSelf().filter(oSelector);
น่าเสียดายที่.andSelf()
ไม่มีตัวเลือกซึ่งจะมีประโยชน์
closest(..)
รวมองค์ประกอบ DOM ปัจจุบันและขึ้นต้นไม้ในขณะที่วิธีการข้ามผ่านแบบลงต้นไม้ทั้งหมดเช่นfind(..)
ฯลฯ ไม่ตรงกับองค์ประกอบปัจจุบัน เหมือนกับว่าทีม jQuery ใช้สิ่งเหล่านี้โดยมีจุดประสงค์เพื่อไม่ให้เกิดการทับซ้อนกันเมื่อการดำเนินการทั้งสองใช้ร่วมกันสำหรับการค้นหาแนวตั้งแบบเต็ม
กำหนด
$.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 ไม่มีในตัวนี้ แปลกจริงๆสำหรับการพัฒนาหลายปี ตัวจัดการ AJAX ของฉันไม่ได้นำไปใช้กับองค์ประกอบยอดนิยมบางอย่างเนื่องจาก. find () ทำงาน
filter()
นั่นซึ่งเข้าท่ากว่า
$('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))
:)
$('selector')
จะถูกแทนที่ด้วยวิธีการอื่นในการรับวัตถุ jQuery หรือไม่ (หากนั่นคือสิ่งที่คุณหมายถึงโดยไม่ได้เริ่มต้นด้วยตัวเลือก) add()
สามารถจัดการกับสิ่งใดก็ได้เช่น$()
กัน
$('selector')
อาจจะ$('selector').children('filter').closest('.class').last()
... มันอาจอยู่ในห่วงโซ่และคุณไม่รู้ว่าวัตถุที่คุณกำลังเพิ่มคืออะไรดังนั้นวิธีการแก้ปัญหาทั่วไปควรใช้วัตถุก่อนหน้าเช่นเดียวกับตัวกรอง :)
this
เป็นวัตถุ jQuery ที่เรียกใช้ปลั๊กอิน อาจเป็นผลมาจากห่วงโซ่การโทร
คำตอบที่ได้รับการยอมรับนั้นไม่มีประสิทธิภาพมากและกรองชุดขององค์ประกอบที่ตรงกันแล้ว
//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);
หากคุณต้องการให้โซ่ทำงานอย่างถูกต้องให้ใช้ข้อมูลโค้ดด้านล่าง
$.fn.findBack = function(expr) {
var r = this.find(expr);
if (this.is(expr)) r = r.add(this);
return this.pushStack(r);
};
หลังจากการเรียกใช้ฟังก์ชันสิ้นสุดจะส่งคืนองค์ประกอบ #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()
ก็พอใจแล้วถ้ามีเพียงหนึ่งในนั้นที่ตรงกัน
ในกรณีที่คุณกำลังมองหาองค์ประกอบเดียวไม่ว่าจะเป็นองค์ประกอบปัจจุบันหรือองค์ประกอบภายในคุณสามารถใช้:
result = elem.is(selector) ? elem : elem.find(selector);
ในกรณีที่คุณกำลังมองหาองค์ประกอบหลายอย่างคุณสามารถใช้ได้:
result = elem.filter(selector).add(elem.find(selector));
การใช้andSelf
/ andBack
ค่อนข้างหายากไม่แน่ใจว่าทำไม บางทีอาจเป็นเพราะปัญหาด้านการแสดงที่ผู้ชายบางคนพูดถึงก่อนหน้าฉัน
(ตอนนี้ฉันสังเกตว่าTgrได้ให้โซลูชันที่สองนั้นแล้ว)
ฉันรู้ว่านี่เป็นคำถามเก่า แต่มีวิธีที่ถูกต้องกว่านี้ หากลำดับมีความสำคัญตัวอย่างเช่นเมื่อคุณจับคู่ตัวเลือกที่ชอบ: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);
};
มันจะไม่มีประสิทธิภาพ แต่อย่างใด แต่เป็นสิ่งที่ดีที่สุดที่ฉันคิดขึ้นมาเพื่อรักษาระเบียบที่เหมาะสม
ฉันคิดว่าandSelf
คือสิ่งที่คุณต้องการ:
obj.find(selector).andSelf()
โปรดทราบว่าสิ่งนี้จะเพิ่มกลับโหนดปัจจุบันเสมอไม่ว่าจะตรงกับตัวเลือกหรือไม่ก็ตาม
หากคุณดูอย่างเคร่งครัดในโหนดปัจจุบันคุณก็แค่ทำ
$(html).filter('selector')
ฉันพยายามหาวิธีแก้ปัญหาที่ไม่ทำซ้ำ (เช่นไม่ป้อนตัวเลือกเดียวกันสองครั้ง)
และส่วนขยาย jQuery เล็ก ๆ นี้ทำ:
jQuery.fn.findWithSelf = function(...args) {
return this.pushStack(this.find(...args).add(this.filter(...args)));
};
มันรวมfind()
(ลูกหลานเท่านั้น) กับfilter()
(เฉพาะชุดปัจจุบัน) และสนับสนุนข้อโต้แย้งใด ๆ ที่ทั้งคู่กิน pushStack()
ช่วยให้.end()
การทำงานเป็นไปตามคาด
ใช้แบบนี้:
$(element).findWithSelf('.target')
นี่คือความจริงที่ถูกต้อง (แต่น่าเศร้า):
$(selector).parent().find(oSelector).filter($(selector).find('*'))
$(selector)
ตัวเองออกจากฉากในทุกกรณี