สำหรับ JS ฉันคิดว่าทุกคนที่ยังใหม่กับมันควรบ่น: ทำไมไม่มีวิธีที่จะได้รับองค์ประกอบผ่านชั้นเรียน แม้ว่าตอนนี้เบราว์เซอร์รุ่นที่สูงกว่าจะสนับสนุนฟังก์ชั่น GetElementsByClassName () แต่ก็ยังคงไม่เข้ากันสำหรับเบราว์เซอร์รุ่นที่ต่ำกว่า เมื่อออกจากห้องสมุดอื่น ๆ คุณยังต้องห่อหุ้มวิธีการด้วยตัวเอง
วิธีที่ 1
ฟังก์ชั่น getByClass1 (parent, cls) {var res = []; // อาร์เรย์ที่เก็บผลลัพธ์ที่ตรงกัน var ele = parent.getElementsByTagname ('*'); สำหรับ (var i = 0; i <ele.length; i ++) {ถ้า (ele [i] .className == cls) {res.push (ele [i]); }} return res;}แน่นอนว่าเมื่อมีค่าเดียวในชั้นเรียนวิธีข้างต้นจะดี แต่เมื่อมีหลายค่าปัญหาจะเกิดขึ้น
<div> </div> <div> </div> <script> getByClass1 (เอกสาร, 'ทดสอบ'); // รับเฉพาะ div แรก </script>
วิธีที่ 2
เมื่อปัญหาเกิดขึ้นเราจะพยายามปรับปรุง สำหรับชื่อหลายคลาสเราสามารถใช้การจับคู่ปกติเพื่อดูว่าชื่อคลาสรวมอยู่หรือไม่ดังนั้นวิธีการเขียนต่อไปนี้จะปรากฏขึ้น:
ฟังก์ชั่น getByClass2 (parent, cls) {var res = []; var reg = ใหม่ regexp ('// b' + cls + '// b', 'i'); // Match CLS เป็นคำที่เป็นอิสระ var ele = parent.getElementsByTagname ('*'); สำหรับ (var i = 0; i <ele.length; i ++) {ถ้า (reg.test (ele [i] .classname)) {res.push (ele [i]); }} return res;}วิธีนี้ดูเหมือนจะโอเคและแก้ไขปัญหาของ getByClass1 () ฉันใช้มันมานานแล้ว แต่ยังมีข้อผิดพลาดที่ซ่อนอยู่ ดูตัวอย่างต่อไปนี้:
<div> </div> <div> </div> <div> </div> </script> getByClass2 (เอกสาร, 'ทดสอบ'); // ผลลัพธ์คือ Div แรกและ Div ที่สาม </script>
ในทางทฤษฎีเราควรได้รับสิ่งแรกเท่านั้น แต่มันแตกต่างจากที่เราคาดไว้ ข้อบกพร่องนี้มีต้นกำเนิดจาก /b ในรหัสต่อไปนี้
var reg = ใหม่ regexp ('// b' + cls + '// b', 'i');ก่อนอื่นให้ดูความหมายของ /b ในปกติ
/B เป็นรหัสพิเศษที่ระบุโดยนิพจน์ทั่วไปซึ่งแสดงถึงจุดเริ่มต้นหรือจุดสิ้นสุดของคำนั่นคือขอบเขตของคำ
เพื่อให้ง่าย: /b คือการจับคู่คำ (จากเส้นขอบด้านซ้ายไปยังเส้นขอบด้านขวา)
ปัญหาอยู่ที่นี่ /B ขอแสดงความนับถืออักขระอื่น ๆ ทั้งหมดยกเว้นตัวอักษรตัวเลขและขีดเส้นใต้เป็นขอบเขต สำหรับตัวอย่างข้างต้นค่าคลาสที่สามคือกล่องทดสอบ เมื่อใด /B จับคู่กันยัติภังค์ (-) ถือเป็นขอบเขตคำดังนั้นมันจึงตรงกับ Div ที่สาม
วิธีที่ 3
ดังนั้นเราจำเป็นต้องทำการปรับปรุงวิธีการข้างต้นเพิ่มเติม ที่นี่เราอ้างถึงวิธีการที่กล่าวถึงใน stackoverflow:
จะรับองค์ประกอบโดยคลาสใน JavaScript ได้อย่างไร?
รหัสที่ได้รับการปรับปรุงมีดังนี้:
ฟังก์ชั่น getByClass3 (parent, cls) {var res = []; var reg = ใหม่ regexp ('' + cls + '', 'i'); // เมื่อจับคู่ CLS จะต้องมีช่องว่างทั้งสองด้าน var ele = parent.getElementsByTagname ('*'); สำหรับ (var i = 0; i <ele.length; i ++) {ถ้า (reg.test ('' + ele [i] .classname + '')) {res.push (ele [i]); }} return res;}วิธีนี้ละทิ้งการใช้ /b และใช้ช่องว่างเพื่อให้ตรงกับขอบเขต ก่อนอื่นเพิ่มช่องว่างไปยังทั้งสองด้านของค่าคลาสที่ได้รับซึ่งทำให้มั่นใจได้ว่าจะมีช่องว่างทั้งสองด้านของแต่ละค่าในชื่อคลาสแล้วใช้ปกติเพื่อจับคู่
ยังไม่พบปัญหาที่ใช้วิธีนี้ แต่เมื่อใช้งานช่องว่างในคำพูดเดียวในวิธีการจะต้องไม่ถูกทิ้ง
วิธีที่ 4
ฟังก์ชั่น getByClass3 (parent, cls) {var res = []; var reg = ใหม่ regexp ('(^| // s)' + cls + '($ | // s)', 'i'); var ele = parent.getElementsByTagname ('*'); สำหรับ (var i = 0; i <ele.length; i ++) {ถ้า (reg.test (ele [i] .classname)) {res.push (ele [i]); }} return res;}ช่องว่างได้รับการจัดการอย่างสม่ำเสมอซึ่งช่วยลดปัญหาของพื้นที่ง่าย ๆ ที่ตกลงมาและรหัสนั้นสวยงามและเรียบง่ายกว่า
วิธีนี้ค่อนข้างสมบูรณ์แบบหรือไม่? ในความเป็นจริงมันไม่ได้ มาดูทางออกที่ดีกว่ากัน
วิธีที่ 5 (ฉบับสมบูรณ์แบบ)
ดังที่ได้กล่าวไว้ในตอนต้นของบทความเบราว์เซอร์เวอร์ชันที่สูงขึ้นสนับสนุนวิธี GetElementsByClassName () ด้วยเหตุผลด้านประสิทธิภาพจึงเป็นการดีกว่าที่จะใช้วิธีการดั้งเดิมสำหรับเบราว์เซอร์ที่รองรับ สำหรับเบราว์เซอร์รุ่นที่ต่ำกว่าให้ใช้วิธีการสี่ด้านบน
ฟังก์ชั่น getByClass (parent, cls) {if (parent.getElementByClassName) {return parent.getElementsByClassName (CLS); } else {var res = []; var reg = new regexp ('' + cls + '', 'i') var ele = parent.getElementByTagname ('*'); สำหรับ (var i = 0; i <ele.length; i ++) {ถ้า (reg.test ('' + ele [i] .classname + '')) {res.push (ele [i]); }} return res; -แน่นอนวิธีการที่ 5 ถือเป็นวิธีแก้ปัญหาที่ค่อนข้างดี หากมีวิธีที่ดีกว่าโปรดฝากข้อความไว้เพื่อเพิ่ม