javascript - ฉันจะเลือกโหนดข้อความด้วย jQuery ได้อย่างไร?
ฉันต้องการดึงโหนดข้อความลูกหลานทั้งหมดขององค์ประกอบหนึ่ง เป็นคอลเลกชัน jQuery วิธีที่ดีที่สุดในการทำเช่นนั้นคืออะไร?
คำตอบ #1
jQuery ไม่มีฟังก์ชันที่สะดวกสำหรับเรื่องนี้ คุณต้องรวม contents() ซึ่งจะให้เฉพาะโหนดลูก แต่รวมโหนดข้อความด้วย กับ find() ซึ่งจะให้ทุกองค์ประกอบลูกหลาน แต่ไม่มีโหนดข้อความ นี่คือสิ่งที่ฉันคิดออก:
var getTextNodesIn = function(el) {
return $(el).find(":not(iframe)").addBack().contents().filter(function() {
return this.nodeType == 3;
});
};
getTextNodesIn(el);
หมายเหตุ: หากคุณกำลังใช้ jQuery 1.7 หรือต่ำกว่า โค้ดด้านบนจะไม่ทำงาน ในการแก้ไข ให้แทนที่ addBack() ด้วย andSelf() andSelf() ถูกยกเลิกการใช้งานและแนะนำให้ใช้ addBack() ตั้งแต่เวอร์ชัน 1.8 เป็นต้นไป
นี่ค่อนข้างไม่มีประสิทธิภาพเมื่อเทียบกับวิธี DOM แท้ๆ และต้องรวมวิธีแก้ไขที่ไม่สวยงามสำหรับการโอเวอร์โหลดฟังก์ชัน contents() ของ jQuery (ขอบคุณ @rabidsnail ในคอมเมนต์ที่ชี้ให้เห็นเรื่องนี้) ดังนั้นนี่คือวิธีแก้ปัญหาแบบไม่ใช้ jQuery โดยใช้ฟังก์ชันเรียกซ้ำง่ายๆ พารามิเตอร์ includeWhitespaceNodes ควบคุมว่าจะรวมโหนดข้อความว่างหรือไม่ในผลลัพธ์ (ใน jQuery พวกมันจะถูกกรองออกโดยอัตโนมัติ)
อัปเดต: แก้ไขบั๊กเมื่อ includeWhitespaceNodes เป็นค่าที่เป็นเท็จ
function getTextNodesIn(node, includeWhitespaceNodes) {
var textNodes = [], nonWhitespaceMatcher = /\S/;
function getTextNodes(node) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || nonWhitespaceMatcher.test(node.nodeValue)) {
textNodes.push(node);
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
getTextNodes(node.childNodes[i]);
}
}
}
getTextNodes(node);
return textNodes;
}
getTextNodesIn(el);
คำตอบ #2
Jauco โพสต์วิธีแก้ปัญหาที่ดีในความคิดเห็น ดังนั้นฉันจึงคัดลอกมันมาที่นี่:
$(elem)
.contents()
.filter(function() {
return this.nodeType === 3; //Node.TEXT_NODE
});
คำตอบ #3
$('body').find('*').contents().filter(function () { return this.nodeType === 3; });
