عند تطوير صفحة ويب ، في كثير من الحالات ، نحتاج إلى تشغيل عناصر تحمل اسم الفصل نفسه ، أي عناصر ذات نفس الفصل. لقد أجريت الاختبار الكتابي بالأمس ولم أجب على سؤال ذي صلة:
يحصل JavaScript على العقدة مع اختبار الفصل في الصفحة
لذلك جمعت بعض المعلومات ذات الصلة وأدرجت طريقتين أعتقد أنهما أفضل. هناك حاجة أيضًا إلى أوجه القصور. آمل أن ينتقد الجميع وتصحيحهم. إذا كان لديك طريقة أفضل ، آمل أن تتمكن من مشاركتها.
الحل 1 حلول جيريمي كيوث
تحدث العم جيريمي كيوث عن طريقة getElementsByclass في القسم الثالث والرابع من كتاب "JavaScript DOM Programming Art" (الإصدار الثاني) (اللغة الإنجليزية: DOM Scripting-Web Design with JavaScript و Document Object Model) ، وتحدثت عن كيفية تطبيق هذه الطريقة في الممتلكات التي لا تدعم هذا الممتلكات (ie6 ، IE7 ، IE8 ، مقتطفات هنا ، وهناك تعديلات في بعض الأماكن.
تمت إضافة طريقة جديدة إلى HTML5 DOM للسماح لنا بالوصول إلى العناصر من خلال اسم الفصل في سمة الفصل ، وهو: GetelmentsByClassName. نظرًا لأن الطريقة جديدة نسبيًا ، فإن بعض تطبيقات DOM لا تملكها بعد ، لذا كن حذرًا عند استخدامها. دعنا أولاً نلقي نظرة على ما يمكن أن تساعده هذه الطريقة ، ثم مناقشة كيفية استخدام هذه الطريقة بشكل موثوق.
على غرار طريقة getelmentsbytagname ، فإن getElementsByClassName يقبل أيضًا معلمة واحدة فقط ، وهو اسم الفصل:
نسخة الكود كما يلي:
getElementsByClassName (الفصل)
تشبه قيمة الإرجاع لهذه الطريقة أيضًا GetElementsByTagName ، وكلاهما عبارة عن مجموعة من العناصر ذات اسم الفصل نفسه. يقوم السطر التالي من الكود بإرجاع صفيف يحتوي على جميع عناصر اسم الفصل "بيع":
نسخة الكود كما يلي:
document.getElementsByClassName ("بيع")
استخدم هذه الطريقة للعثور على عناصر بأسماء فصول متعددة. لتحديد أسماء فصول متعددة ، فقط افصل أسماء الفصول مع المسافات في معلمات السلسلة. على سبيل المثال ، أضف السطر التالي من التعليمات البرمجية إلى علامة <script>:
نسخة الكود كما يلي:
ALERT (document.getElementsByClassName ("Sale Target"). الطول) ؛
رمز كامل
نسخة الكود كما يلي:
<! doctype html>
<html>
<head>
<meta charset = "utf-8">
<title> قائمة التسوق </title>
</head>
<body>
<H1> ماذا تشتري </h1>
<p> لا تنسى شراء هذه الأشياء. </p>
<ul id = "شراء">
<li> رقيقة من الفول </li>
<li> الجبن </li>
<li> الحليب </li>
</ul>
<script>
ALERT (document.getElementsByClassName ("Sale Target"). الطول) ؛
</script>
</body>
</html>
سترى 1 في صندوق التحذير ، مما يشير إلى أن عنصرًا واحدًا فقط يتطابق ، لأن عنصرًا واحدًا فقط له أسماء فئة "المهم" و "البيع". لاحظ أنه حتى في سمة الفصل لعنصر ما ، فإن ترتيب أسماء الفصول هو "بيع مهم" بدلاً من "البيع المهم" المحدد في المعلمة ، فسيظل يتطابق مع العنصر. لا يهم فقط الترتيب الفعلي لأسماء الفصول الدراسية ، بل لا يهم حتى لو كان للعناصر المزيد من أسماء الفصول الدراسية. مثل استخدام getelmentsbytagname ، يمكنك أيضًا استخدام getElementsByClassName و getElementById في تركيبة. إذا كنت ترغب في معرفة عدد أسماء الفصول التي تحتوي على عناصر قائمة اختبار في عنصر مع شراء المعرف ، يمكنك العثور على هذا الكائن المحدد أولاً ، ثم اتصل بـ getElementsByClassName:
نسخة الكود كما يلي:
var Shopping = document.getElementById ("شراء") ؛
var sales = Shopping.getElementSbyClassName ("sale") ؛
وبهذه الطريقة ، يحتوي صفيف المبيعات على عناصر فقط مع فئة "المبيعات" الموجودة في قائمة "الشراء". قم بتشغيل السطر التالي من التعليمات البرمجية وسترى أن صفيف المبيعات يحتوي على عنصرين:
نسخة الكود كما يلي:
تنبيه (Sales.Length) ؛
هذه طريقة getelmentsbyclassname مفيدة للغاية ، ولكن المتصفحات الأحدث فقط (Safari 3.1 ، Chorme ، Firefox 3 و Opera 9.5 أو أعلى) تدعمها. للتعويض عن هذا العيب ، يحتاج مبرمجي Script DOM إلى استخدام أساليب DOM الحالية لتنفيذ GetElementsByClassName ، والتي تشبه إلى حد ما هدية قادمة. في معظم الحالات ، تشبه عملية التنفيذ الخاصة بهم تقريبًا GetElementsByClassName ، والتي يمكن تطبيقها على المتصفحات الجديدة والقديمة.
نسخة الكود كما يلي:
وظيفة getElementsByClassName (العقدة ، className) {
if (node.getelementsbyclassname) {
return node.getElementsByClassName (className) ؛
}آخر{
نتائج var = [] ؛
var elems = node.getElementSbyTagName ("*") ؛
لـ (var i = 0 ؛ i <elems.length ؛ i ++) {
if (elems [i] .classname.indexof (className)! =-1) {
النتائج [النتائج. الطول] = elems [i] ؛
}
}
نتائج العودة
}
}
تقبل وظيفة getElementsByClassName معلمتين. تمثل العقدة الأولى نقطة بدء البحث في شجرة DOM ، والاسم الثاني هو اسم الفصل الذي سيتم البحث عنه. إذا كانت وظيفة getElementsByClassName المناسبة موجودة بالفعل على العقدة الواردة ، فإن هذه الوظيفة الجديدة تُرجع مباشرة قائمة العقدة المقابلة. إذا لم تكن وظيفة getElementSbyClassName ، فستكون الوظيفة الجديدة تحلق من خلال جميع العلامات وتبحث عن عناصر تحمل اسم الفئة المقابلة.
عيب هذه الطريقة هو أنه لا ينطبق على أسماء فصول متعددة.
إذا كنت تستخدم هذه الوظيفة لمحاكاة العملية السابقة للحصول على قائمة التسوق ، فيمكنك كتابتها مثل هذا:
نسخة الكود كما يلي:
var Shopping = document.getElementById ("شراء") ؛
var sales = Shopping.getElementsByClassName (التسوق ، "اختبار") ؛
console.log (المبيعات) ؛
لذلك ، لحل المشكلة في بداية المقالة ، فإن الكود المستخدم هو كما يلي:
نسخة الكود كما يلي:
<! doctype html>
<html>
<head>
<meta charset = "utf-8">
<title> قائمة التسوق </title>
</head>
<body>
<H1> ماذا تشتري </h1>
<p> لا تنسى شراء هذه الأشياء. </p>
<ul id = "شراء">
<li> رقيقة من الفول </li>
<li> الجبن </li>
<li> الحليب </li>
</ul>
<script>
وظيفة getElementsByClassName (العقدة ، className) {
if (node.getelementsbyclassname) {
return node.getElementsByClassName (className) ؛
}آخر{
نتائج var = [] ؛
var elems = node.getElementSbyTagName ("*") ؛
لـ (var i = 0 ؛ i <elems.length ؛ i ++) {
if (elems [i] .classname.indexof (className)! =-1) {
النتائج [النتائج. الطول] = elems [i] ؛
}
}
نتائج العودة
}
}
var body = document.getElementSbyTagName ("body") [0] ؛
var sales = getElementsByClassName (الجسم ، "المبيعات") ؛
console.log (المبيعات) ؛
</script>
</body>
</html>
الحل 2 Robert Nyman Solution
هناك العديد من الطرق للبحث عن مطابقة عناصر DOM ، ولكن ليس الكثير من الكفاءة. أحد عيب العم Jeremy Keuth هو أنه لا يمكن استخدامه لأسماء فصول متعددة. في عام 2008 ، قدم روبرت نيمان حله الخاص في المقالة The Ultimate GetElementsByClassName ، Anno 2008. في عام 2005 ، كان العم روبرت قد أعطى بالفعل وظيفة getElementsByClassName. في عام 2008 ، قام بتعديل بعض التعليمات البرمجية وأضاف العديد من الوظائف الجديدة:
1. إذا كان المتصفح الحالي يدعم وظيفة getElementsByClassName ، فإن الوظيفة الأصلية تسمى ؛
2. إذا كان المتصفح الحالي يدعمه ، فاستخدم XPath ؛ // Xiaofeiyu: طريقة قوية لتحديد مستندات XML التي تم إنشاؤها في المتصفح ، لكن دعم المتصفح غير موحد
3. يدعم البحث عن أسماء فصول متعددة بغض النظر عن الطلب ؛
4. إرجاع مجموعة العقدة الحقيقية ، وليس الإيماءة الأصلية. // xiaofeiyu: تقوم طريقة getElementsByClassName الأصلية بإرجاع كائن 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 Elements = ELM.GetElementsByClassName (className) ،
nodeName = (علامة)؟ regexp جديد ("// b" + tag + "// b" ، "i"): NULL ،
العوائد = [] ،
حاضِر؛
لـ (var i = 0 ، il = elements.length ؛ i <il ؛ i+= 1) {
الحالي = العناصر [i] ؛
if (! nodeName || nodename.test (current.nodename)) {
returnelements.push (الحالي) ؛
}
}
إرجاع الإرجاع ؛
} ؛
}
وإلا إذا
getElementsByClassName = function (className ، tag ، elm) {
علامة = علامة || "*" ؛
elm = elm || وثيقة؛
فئات var = classname.split ("") ،
كلاسيكيك = "" ،
xhtmlnamespace = "http://www.w3.org/1999/xhtml" ،
مسملة الأسماء = (document.documentElement.namespaceuri === xHtmlNamesPace)؟ Xhtmlnamespace: NULL ،
العوائد = [] ،
عناصر،
العقدة؛
لـ (var j = 0 ، jl = classes.length ؛ j <jl ؛ j+= 1) {
ClassestoCheck + = "[يحتوي على (concat ('' ، class ، '') ، '" + classes [j] + "')]" ؛
}
يحاول {
العناصر = document.evaluate (".//" + tag + classestocheck ، elm ، pspaceresolver ، 0 ، null) ؛
}
catch (e) {
العناصر = document.evalTuer (".//" + tag + classestocheck ، elm ، null ، 0 ، null) ؛
}
بينما ((node = elements.iteratenext ())) {
returnelements.push (العقدة) ؛
}
إرجاع الإرجاع ؛
} ؛
}
آخر {
getElementsByClassName = function (className ، tag ، elm) {
علامة = علامة || "*" ؛
elm = elm || وثيقة؛
فئات var = classname.split ("") ،
كلاسيكيك = [] ،
عناصر = (علامة === "*" && elm.all)؟ ElM.All: Elm.getElementsbyTagname (TAG) ،
حاضِر،
العوائد = [] ،
مباراة؛
لـ (var k = 0 ، kl = classes.length ؛ k <kl ؛ k+= 1) {
ClassestoCheck.push (جديد regexp ("(^| // s)" + classes [k] + "(// s | $)") ؛
}
لـ (var l = 0 ، ll = elements.length ؛ l <ll ؛ l+= 1) {
الحالي = العناصر [l] ؛
تطابق = خطأ ؛
لـ (var m = 0 ، ml = classestocheck.length ؛ m <ml ؛ m+= 1) {
match = classestoCheck [m] .test (current.className) ؛
إذا (! تطابق) {
استراحة؛
}
}
إذا (تطابق) {
returnelements.push (الحالي) ؛
}
}
إرجاع الإرجاع ؛
} ؛
}
إرجاع getElementsByClassName (className ، tag ، elm) ؛
} ؛