بالنسبة إلى JS ، أعتقد أن كل من جديد عليها يجب أن يشكو: لماذا لا توجد طريقة للحصول على عناصر من خلال الفصل. على الرغم من أن الإصدارات العليا من المتصفحات تدعم الآن وظيفة getElementsByClassName () ، إلا أنها لا تزال غير متوافقة مع الإصدارات المنخفضة من المتصفحات. عند مغادرة المكتبات الأخرى ، لا يزال يتعين عليك تغليف طريقة بنفسك.
الطريقة 1
وظيفة getByClass1 (الأصل ، cls) {var res = [] ؛ // Array التي تخزن نتائج مطابقة var eLe = parent.getElementsByTagName ('*') ؛ لـ (var i = 0 ؛ i <ele.length ؛ i ++) {if (eLe [i] .className == cls) {res.push (eLe [i]) ؛ }} resever res ؛}بالطبع ، عندما تكون هناك قيمة واحدة فقط في الفصل ، فإن الطريقة أعلاه جيدة ، ولكن عندما تكون هناك قيم متعددة ، ستنشأ مشاكل.
<viv> </viv> <viv> </viv> <script> getByClass1 (وثيقة ، 'test') ؛ // احصل على أول Div </script>
الطريقة 2
عندما تنشأ المشكلات ، سنحاول التحسن. بالنسبة للأسماء متعددة الفقاري ، يمكننا استخدام المطابقة العادية لمعرفة ما إذا كان اسم الفصل مضمنًا ، لذلك تظهر طريقة الكتابة التالية:
وظيفة getByClass2 (الأصل ، cls) {var res = [] ؛ var reg = new regexp ('// b' + cls + '// b' ، 'i') ؛ // MATCH CLS هي كلمة مستقلة var eLe = parent.getElementsByTagName ('*') ؛ لـ (var i = 0 ؛ i <ele.length ؛ i ++) {if (reg.test (eLe [i] .className)) {res.push (eLe [i]) ؛ }} resever res ؛}يبدو أن هذه الطريقة على ما يرام وحل مشكلة getByclass1 (). لقد استخدمته لفترة طويلة ، ولكن لا يزال هناك خطأ خفي. انظر المثال التالي:
<viv> </viv> <viv> </viv> <viv> </viv> <script> getByClass2 (وثيقة ، 'test') ؛ // النتيجة هي Div الأولى والثالث Div </script>
من الناحية النظرية ، يجب أن نحصل على الأول فقط ، لكنه يختلف عن ما توقعناه. ينبع هذا الخطأ من /B في الكود التالي
var reg = new regexp ('// b' + cls + '// b' ، 'i') ؛دعونا نلقي نظرة أولاً على معنى /B في العادية
/B هو رمز خاص يحدده تعبير منتظم ، يمثل بداية أو نهاية كلمة ، أي حدود الكلمة.
بعبارة ببساطة: /B هو مطابقة كلمة (من الحدود اليسرى إلى الحدود اليمنى).
المشكلة تكمن هنا. /B فيما يتعلق بجميع الأحرف الأخرى باستثناء الحروف والأرقام والرسم السفلي كحدود. بالنسبة للمثال أعلاه ، فإن قيمة الفئة الثالثة هي صندوق الاختبار. عندما يطابق /B ، يُعتبر الواصلة (-) ككلمة الحدود ، بحيث تتطابق مع Div الثالث.
الطريقة 3
لذلك ، نحن بحاجة إلى إجراء مزيد من التحسينات على الطريقة أعلاه. هنا نشير إلى طريقة مذكورة على Stackoverflow:
كيف تحصل على عنصر حسب الفصل في JavaScript؟
الرمز المحسن كما يلي:
دالة getByClass3 (الأصل ، cls) {var res = [] ؛ var reg = new regexp ('' + cls + '' ، 'i') ؛ // عند مطابقة CLS ، يجب أن تكون هناك مسافات على كلا الجانبين var eLe = parent.getElementsByTagName ('*') ؛ لـ (var i = 0 ؛ i <ele.length ؛ i ++) {if (reg.test ('' + eLe [i] .className + '')) {res.push (eLe [i]) ؛ }} resever res ؛}تتخلى هذه الطريقة عن استخدام /B وتستخدم المساحات لمطابقة الحدود. أضف أولاً مسافات إلى جانبي قيمة اسم الفئة التي تم الحصول عليها ، والتي تضمن أنه ستكون هناك مسافات على جانبي كل قيمة في اسم className ، ثم استخدمها بشكل منتظم للمطابقة.
لم يتم العثور على مشكلة باستخدام هذه الطريقة حتى الآن ، ولكن عند استخدامها ، يجب عدم إسقاط المساحات في عروض أسعار واحدة في الطريقة.
الطريقة 4
دالة getByClass3 (الأصل ، cls) {var res = [] ؛ var reg = new regexp ('(^| // s)' + cls + '($ | // s)' ، 'i') ؛ var eLe = parent.getElementSbyTagName ('*') ؛ لـ (var i = 0 ؛ i <ele.length ؛ i ++) {if (reg.test (eLe [i] .className)) {res.push (eLe [i]) ؛ }} resever res ؛}تتم معالجة المساحات تمامًا بانتظام ، مما يلغي مشكلة انخفاض المساحات السهلة والرمز أكثر جمالًا وبسيطة.
فهل هذه الطريقة مثالية نسبيا؟ في الواقع ، ليس كذلك. دعونا نلقي نظرة على حل أفضل.
الطريقة 5 (طبعة مثالية)
كما ذكرنا في بداية المقالة ، تدعم إصدارات أعلى من المتصفحات بالفعل طريقة getElementsByClassName (). لأسباب الأداء ، من المحتم أن يكون من الأفضل استخدام الأساليب الأصلية للمتصفحات المدعومة. للإصدارات المنخفضة من المتصفحات ، استخدم الطريقة الرابعة أعلاه.
وظيفة getByClass (Parent ، cls) {if (parent.getElementSbyClassName) {return parent.getElementSbyClassName (cls) ؛ } آخر {var res = [] ؛ var reg = new regexp ('' + cls + '' ، 'i') var eLe = parent.getElementSbyTagName ('*') ؛ لـ (var i = 0 ؛ i <ele.length ؛ i ++) {if (reg.test ('' + eLe [i] .className + '')) {res.push (eLe [i]) ؛ }} return res ؛ }}بالطبع ، تعتبر الطريقة 5 حلًا جيدًا نسبيًا. إذا كانت هناك طريقة أفضل ، فيرجى ترك رسالة لإضافتها.