เมื่อพัฒนาเว็บเพจในหลายกรณีเราจำเป็นต้องใช้องค์ประกอบที่มีชื่อคลาสเดียวกันนั่นคือองค์ประกอบที่มีคลาสเดียวกัน ฉันทำการทดสอบเป็นลายลักษณ์อักษรเมื่อวานนี้และฉันไม่ได้ตอบคำถามที่เกี่ยวข้อง:
JavaScript ได้รับโหนดพร้อมการทดสอบคลาสในหน้า
ดังนั้นฉันจึงรวบรวมข้อมูลที่เกี่ยวข้องและแสดงสองวิธีที่ฉันคิดว่าดีกว่า ข้อบกพร่องก็จำเป็นเช่นกัน ฉันหวังว่าทุกคนจะวิพากษ์วิจารณ์และแก้ไขพวกเขา หากคุณมีวิธีที่ดีกว่าฉันหวังว่าคุณจะแบ่งปันได้
โซลูชัน 1 Jeremy Keuth Solution
ลุง Jeremy Keuth พูดคุยเกี่ยวกับวิธีการ getElementsByClass ในส่วนที่สามและสี่ของหนังสือ "JavaScript Dom Programming Art" (ฉบับที่ 2) (ภาษาอังกฤษ: การออกแบบ Dom Scripting-Web กับ JavaScript และโมเดลวัตถุเอกสาร) และพูดคุยเกี่ยวกับวิธีการใช้วิธีนี้ ข้อความที่ตัดตอนมาอยู่ที่นี่และมีการปรับเปลี่ยนในบางสถานที่
มีการเพิ่มวิธีการใหม่ใน HTML5 DOM เพื่อให้เราสามารถเข้าถึงองค์ประกอบผ่านชื่อคลาสในแอตทริบิวต์คลาสซึ่งก็คือ: GetElmentsByClassName เนื่องจากวิธีการค่อนข้างใหม่การใช้งาน DOM บางอย่างยังไม่มีดังนั้นโปรดระวังเมื่อใช้งาน ก่อนอื่นมาดูว่าวิธีนี้สามารถช่วยเราได้อย่างไรจากนั้นอภิปรายวิธีการใช้วิธีนี้อย่างน่าเชื่อถือ
คล้ายกับวิธี getElmentsByTagname, getElementsByClassName ยังยอมรับพารามิเตอร์เดียวเท่านั้นซึ่งเป็นชื่อคลาส:
การคัดลอกรหัสมีดังนี้:
getElementsByClassName (คลาส)
ค่าส่งคืนของวิธีนี้ก็คล้ายกับ GetElementsByTagname ทั้งคู่เป็นอาร์เรย์ขององค์ประกอบที่มีชื่อคลาสเดียวกัน บรรทัดของรหัสต่อไปนี้ส่งคืนอาร์เรย์ที่มีองค์ประกอบทั้งหมดของชื่อคลาส "Sale":
การคัดลอกรหัสมีดังนี้:
document.getElementByClassName ("ขาย")
ใช้วิธีนี้เพื่อค้นหาองค์ประกอบที่มีชื่อหลายคลาส ในการระบุชื่อหลายคลาสให้แยกชื่อคลาสด้วยช่องว่างในพารามิเตอร์สตริง ตัวอย่างเช่นเพิ่มบรรทัดของรหัสต่อไปนี้ไปยังแท็ก <Script>:
การคัดลอกรหัสมีดังนี้:
การแจ้งเตือน (document.getElementsByClassName ("การขายสำคัญ"). ความยาว);
กรอกรหัส
การคัดลอกรหัสมีดังนี้:
<! doctype html>
<html>
<head>
<meta charset = "utf-8">
<tite> รายการช้อปปิ้ง </title>
</head>
<body>
<H1> ซื้ออะไร </h1>
<p> อย่าลืมซื้อสิ่งนี้ </p>
<ul id = "ซื้อ">
<li> ถั่วบาง ๆ </li>
<li> ชีส </li>
<li> นม </li>
</ul>
<script>
การแจ้งเตือน (document.getElementsByClassName ("การขายสำคัญ"). ความยาว);
</script>
</body>
</html>
คุณจะเห็น 1 ในช่องเตือนซึ่งระบุว่ามีเพียงองค์ประกอบเดียวที่ตรงกันเพราะองค์ประกอบเดียวเท่านั้นที่มีทั้งชื่อคลาส "สำคัญ" และ "ขาย" โปรดทราบว่าแม้ในแอตทริบิวต์คลาสขององค์ประกอบลำดับของชื่อคลาสคือ "การขายสำคัญ" มากกว่า "การขายที่สำคัญ" ที่ระบุในพารามิเตอร์มันจะยังคงตรงกับองค์ประกอบ ไม่เพียง แต่ลำดับที่แท้จริงของชื่อคลาสไม่สำคัญ แต่ไม่สำคัญแม้ว่าองค์ประกอบจะมีชื่อคลาสมากขึ้น เช่นเดียวกับการใช้ GetElmentsByTagname คุณยังสามารถใช้ GetElementsByClassName และ GetElementById ร่วมกันได้ หากคุณต้องการทราบว่าชื่อคลาสมีจำนวนรายการทดสอบในองค์ประกอบที่มีการซื้อ ID คุณสามารถค้นหาวัตถุเฉพาะนั้นก่อนจากนั้นเรียก getElementsByClassName:
การคัดลอกรหัสมีดังนี้:
var Shopping = document.getElementById ("ซื้อ");
var sales = shopping.getElementsByClassName ("sale");
ด้วยวิธีนี้อาร์เรย์การขายมีเพียงองค์ประกอบที่มีคลาส "การขาย" ที่อยู่ในรายการ "ซื้อ" เรียกใช้รหัสบรรทัดต่อไปนี้และคุณจะเห็นว่าอาร์เรย์ขายมีสองรายการ:
การคัดลอกรหัสมีดังนี้:
การแจ้งเตือน (sales.length);
วิธีการ getElmentsByClassName นี้มีประโยชน์มาก แต่เฉพาะเบราว์เซอร์ใหม่ (Safari 3.1, Chorme, Firefox 3 และ Opera 9.5 หรือสูงกว่า) รองรับ ในการชดเชยข้อบกพร่องนี้โปรแกรมเมอร์ DOM Script จำเป็นต้องใช้วิธีการ DOM ที่มีอยู่เพื่อใช้งาน GetElementsByClassName ซึ่งเป็นของกำนัลที่กำลังจะมาถึง ในกรณีส่วนใหญ่กระบวนการดำเนินการของพวกเขาจะคล้ายกับ getElementsByClassName ต่อไปนี้ซึ่งสามารถนำไปใช้กับเบราว์เซอร์ใหม่และเก่า
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น getElementsByClassName (โหนด, className) {
if (node.getElementsByClassName) {
ส่งคืน node.getElementsByClassName (className);
}อื่น{
ผลลัพธ์ var = [];
var elems = node.getElementsByTagname ("*");
สำหรับ (var i = 0; i <elems.length; i ++) {
if (elems [i] .classname.indexof (classname)! =-1) {
ผลลัพธ์ [results.length] = elems [i];
-
-
ผลลัพธ์กลับมา;
-
-
ฟังก์ชั่น getElementsByClassName ยอมรับพารามิเตอร์สองพารามิเตอร์ โหนดแรกแสดงถึงจุดเริ่มต้นการค้นหาในแผนผัง DOM และชื่อคลาสที่สองคือชื่อคลาสที่จะค้นหา หากฟังก์ชัน getElementsByClassName ที่เหมาะสมมีอยู่แล้วในโหนดที่เข้ามาแล้วฟังก์ชั่นใหม่นี้จะส่งคืนรายการโหนดที่เกี่ยวข้องโดยตรง หากไม่มีฟังก์ชั่น getElementsByClassName ฟังก์ชั่นใหม่จะวนซ้ำผ่านแท็กทั้งหมดและค้นหาองค์ประกอบที่มีชื่อคลาสที่สอดคล้องกัน
ข้อเสียของวิธีนี้คือมันไม่ได้ใช้กับชื่อหลายคลาส
หากคุณใช้ฟังก์ชั่นนี้เพื่อจำลองการดำเนินการก่อนหน้านี้ในการรับรายการช้อปปิ้งคุณสามารถเขียนได้เช่นนี้:
การคัดลอกรหัสมีดังนี้:
var Shopping = document.getElementById ("ซื้อ");
var sales = shopping.getElementsByClassName (ช็อปปิ้ง, "ทดสอบ");
console.log (ยอดขาย);
ดังนั้นเพื่อแก้ปัญหาที่จุดเริ่มต้นของบทความรหัสที่ใช้มีดังนี้:
การคัดลอกรหัสมีดังนี้:
<! doctype html>
<html>
<head>
<meta charset = "utf-8">
<tite> รายการช้อปปิ้ง </title>
</head>
<body>
<H1> ซื้ออะไร </h1>
<p> อย่าลืมซื้อสิ่งนี้ </p>
<ul id = "ซื้อ">
<li> ถั่วบาง ๆ </li>
<li> ชีส </li>
<li> นม </li>
</ul>
<script>
ฟังก์ชั่น getElementsByClassName (โหนด, className) {
if (node.getElementsByClassName) {
ส่งคืน node.getElementsByClassName (className);
}อื่น{
ผลลัพธ์ var = [];
var elems = node.getElementsByTagname ("*");
สำหรับ (var i = 0; i <elems.length; i ++) {
if (elems [i] .classname.indexof (classname)! =-1) {
ผลลัพธ์ [results.length] = elems [i];
-
-
ผลลัพธ์กลับมา;
-
-
var body = document.getElementsByTagname ("body") [0];
var sales = getElementsByClassName (body, "sales");
console.log (ยอดขาย);
</script>
</body>
</html>
โซลูชัน 2 Robert Nyman Solution
มีหลายวิธีในการค้นหาองค์ประกอบการจับคู่ DOM แต่มีไม่มากที่มีประสิทธิภาพอย่างแท้จริง ข้อเสียอย่างหนึ่งของวิธีการของลุง Jeremy Keuth คือมันไม่สามารถใช้สำหรับชื่อชั้นเรียนหลายชื่อ ในปี 2008 Robert Nyman ได้จัดหาวิธีแก้ปัญหาของเขาเองในบทความ The Ultimate GetElementsByclassName, Anno 2008 ในปี 2005 ลุงโรเบิร์ตได้ให้ฟังก์ชั่น getElementsByClassName แล้ว ในปี 2008 เขาแก้ไขรหัสบางส่วนและเพิ่มฟังก์ชั่นใหม่ ๆ มากมาย:
1. หากเบราว์เซอร์ปัจจุบันรองรับฟังก์ชัน getElementsByClassName ฟังก์ชันดั้งเดิมจะเรียกว่า;
2. หากเบราว์เซอร์ปัจจุบันรองรับให้ใช้ XPath; // Xiaofeiyu: วิธีที่ทรงพลังในการค้นหาเอกสาร XML ที่สร้างขึ้นในเบราว์เซอร์ แต่การสนับสนุนเบราว์เซอร์ไม่ได้เป็นหนึ่งเดียว
3. สนับสนุนการค้นหาชื่อหลายคลาสโดยไม่คำนึงถึงการสั่งซื้อ
4. ส่งคืนอาร์เรย์โหนดจริงไม่ใช่ผู้ที่มีเนทีฟเนทีฟ // Xiaofeiyu: วิธีการ getElementsByClassName ดั้งเดิมส่งคืนวัตถุ nodelist ซึ่งคล้ายกับอาร์เรย์ที่มีคุณสมบัติความยาวและตัวเลขดัชนี แต่ไม่ใช่อาร์เรย์และคุณไม่สามารถใช้วิธีการเฉพาะอาร์เรย์เช่น POP และ PUSH ในรหัสที่จัดทำโดย Robert วัตถุ Nodelist จะถูกแปลงเป็นอาร์เรย์ วิธีการที่วัตถุโหนดสามารถแปลงเป็นอาร์เรย์ได้:
การคัดลอกรหัสมีดังนี้:
mylist = array.prototype.slice.call (mynodelist)
นี่คือวิธีการของลุงโรเบิร์ต ฉันไม่เข้าใจบางสิ่งที่ฉันยังไม่เข้าใจ ฉันจะอัปเดตหลังจากเรียนพวกเขา
การคัดลอกรหัสมีดังนี้:
-
พัฒนาโดย Robert Nyman, http://www.robertnyman.com
รหัส/ใบอนุญาต: http://code.google.com/p/getElementSbyClassName/
-
var getElementsByClassName = function (className, tag, elm) {
if (document.getElementsByClassName) {
getElementsByClassName = function (className, tag, elm) {
Elm = Elm || เอกสาร;
องค์ประกอบ var = elm.getElementsByClassName (className)
nodeName = (แท็ก)? ใหม่ regexp ("// b" + tag + "// b", "i"): null,
returnElements = []
ปัจจุบัน;
สำหรับ (var i = 0, il = elements.length; i <il; i+= 1) {
current = องค์ประกอบ [i];
if (! nodeName || nodeName.test (current.nodeName)) {
returnElements.push (ปัจจุบัน);
-
-
returnElements;
-
-
อื่นถ้า (document.evaluate) {
getElementsByClassName = function (className, tag, elm) {
tag = tag || -
Elm = Elm || เอกสาร;
var classes = classname.split ("")
classestocheck = ""
xhtmlnamespace = "http://www.w3.org/1999/xhtml"
namespaceresolver = (document.documentelement.namespaceuri === xhtmlnamespace)? XHTMLNAMESPACE: NULL,
returnElements = []
องค์ประกอบ
โหนด;
สำหรับ (var j = 0, jl = classes.length; j <jl; j+= 1) {
classestocheck + = "[มี (concat ('', @class, ''), '" + คลาส [j] + "')]";
-
พยายาม {
Elements = document.evaluate (".//" + tag + classestocheck, elm, namespaceresolver, 0, null);
-
จับ (e) {
Elements = document.evaluate (".//" + tag + classestocheck, elm, null, 0, null);
-
ในขณะที่ ((node = exliement.iteratenext ())) {
returnElements.push (โหนด);
-
returnElements;
-
-
อื่น {
getElementsByClassName = function (className, tag, elm) {
tag = tag || -
Elm = Elm || เอกสาร;
var classes = classname.split ("")
classestocheck = []
Elements = (tag === "*" && elm.all)? Elm.all: Elm.getElementsByTagname (TAG)
ปัจจุบัน,
returnElements = []
จับคู่;
สำหรับ (var k = 0, kl = classes.length; k <kl; k+= 1) {
classestocheck.push (ใหม่ regexp ("(^| // s)" + คลาส [k] + "(// s | $)"));
-
สำหรับ (var l = 0, ll = elements.length; l <ll; l+= 1) {
current = องค์ประกอบ [l];
จับคู่ = เท็จ;
สำหรับ (var m = 0, ml = classestocheck.length; m <ml; m+= 1) {
match = classestocheck [m] .test (current.classname);
ถ้า (! จับคู่) {
หยุดพัก;
-
-
ถ้า (จับคู่) {
returnElements.push (ปัจจุบัน);
-
-
returnElements;
-
-
ส่งคืน getElementsByClassName (className, TAG, Elm);
-