مجموعة Javascript لكائنات DOM - لماذا لا يمكنني عكسها باستخدام Array.reverse()؟

StackOverflow https://stackoverflow.com/questions/45613

  •  09-06-2019
  •  | 
  •  

سؤال

ما المشكلة في عكس مصفوفة كائنات DOM كما في الكود التالي:

var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();

في Firefox 3، عندما أتصل بـ reverse() يتوقف البرنامج النصي عن التنفيذ ويظهر الخطأ التالي في وحدة التحكم الخاصة بشريط أدوات مطور الويب:

imagesArr.reverse is not a function

ال imagesArr يمكن تكرار المتغير من خلال حلقة for وعناصر مثل imagesArr[i] يمكن الوصول إليها، فلماذا لا يتم رؤيتها كمصفوفة عند استدعاء reverse() طريقة؟

هل كانت مفيدة؟

المحلول

لأن اسم getElementsByTag يُرجع فعليًا بنية NodeList.لديها مجموعة مماثلة مثل خصائص الفهرسة للراحة النحوية، ولكنها كذلك لا مجموعة.على سبيل المثال، يتم في الواقع تحديث مجموعة الإدخالات ديناميكيًا باستمرار - إذا قمت بإضافة علامة img جديدة ضمن myDivHolderId، فسوف تظهر تلقائيًا في ImagesArr.

يرى http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 للمزيد من.

نصائح أخرى

getElementsByTag() تقوم بإرجاع NodeList بدلاً من Array.يمكنك تحويل NodeList إلى Array ولكن لاحظ أن المصفوفة ستكون كائنًا آخر، لذا فإن عكسها لن يؤثر على موضع عقد DOM.

var listNodes = document.getElementById("myDivHolderId").getElementsByTagName("img");
var arrayNodes = Array.slice.call(listNodes, 0);
arrayNodes.reverse();

لتغيير الموضع، سيتعين عليك إزالة عقد DOM وإضافتها جميعًا مرة أخرى في الموضع الصحيح.

Array.prototype.slice.call(arrayLike, 0) هي طريقة رائعة لتحويل مصفوفة تشبه المصفوفة، ولكن إذا كنت تستخدم مكتبة JavaScript، فقد توفر طريقة أفضل/أسرع للقيام بذلك.على سبيل المثال، لدى jQuery $.makeArray(arrayLike).

يمكنك أيضًا استخدام أساليب Array مباشرةً في NodeList:

Array.prototype.reverse.call(listNodes);

getElementsByTag() تقوم بإرجاع NodeList بدلاً من Array.تحتاج إلى تحويل NodeList إلى مصفوفة ثم عكسها.

var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();

أعلم أن هذا السؤال قديم ولكن أعتقد أنه يحتاج إلى القليل من التوضيح حيث أن بعض الإجابات هنا قديمة حيث قام W3C بتغيير التعريف، وبالتالي القيمة المرجعة لهذه الأساليب getElementsByTagName() و getElementsByClassName()

هذه الأساليب اعتبارا من وقت كتابة هذه الإجابة إرجاع كائن - فارغ أم لا - من النوع HTMLCollection و لا NodeList.

إنه مثل الفرق بين الخصائص children الذي يقوم بإرجاع كائن من النوع HTMLCollection نظرًا لأنه يتكون فقط من عناصر ويستبعد عقد النص أو التعليق، و childNodes الذي يقوم بإرجاع كائن من النوع NodeList لأنه يمكن أن يحتوي على أنواع عقدة أخرى مثل النص والتعليقات أيضًا.

ملحوظة:سأستمر هنا وأعبر عن افتقاري إلى المعرفة حول السبب querySelectorAll() الطريقة ترجع حاليا أ NodeList وليس HTMLCollection لأنه يعمل حصريًا على عقد العناصر في المستند ولا شيء آخر.

من المحتمل أن يكون له علاقة بالتغطية المحتملة لأنواع العقد الأخرى في المستقبل، وقد ذهبوا إلى حل أكثر إثباتًا للمستقبل، من يدري حقًا؟:)

يحرر:أعتقد أنني حصلت على الأساس المنطقي وراء هذا القرار لاختيار أ NodeList وليس HTMLCollection ل querySelectorAll().

منذ أن بنوا HTMLCollection أن تكون مباشرة بشكل حصري وكامل وبما أن هذه الطريقة لا تحتاج إلى هذه الوظيفة المباشرة، فقد قرروا NodeList التنفيذ بدلا من ذلك لخدمة غرضها على أفضل وجه اقتصاديا وكفاءة.

السطر الأول ليس له أي صلة، لأنه لا يفرض التعيين على المتغير، وتعمل جافا سكريبت في الاتجاه الآخر.ImagesArr، ليس من النوع Array()، مهما كان نوع الإرجاع الخاص بـ getElementsByTagName("img").في هذه الحالة، فهي مجموعة Html في Firefox 3.

الأساليب الوحيدة لهذا الكائن هي المفهرسات والطول.من أجل العمل في الاتجاه المعاكس، ما عليك سوى التكرار للخلف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top