জেএস: অ্যারে.এফ.এইচ ব্যবহার করে getElementsByClassName ফলাফলের উপর পুনরাবৃত্তি


240

আমি কয়েকটি ডিওএম উপাদান নিয়ে পুনরাবৃত্তি করতে চাই, আমি এটি করছি:

document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
  //do stuff
});

তবে আমি একটি ত্রুটি পেয়েছি:

ডকুমেন্ট.জেটএলমেন্টস বাইক্লাসনাম ("মাইক্লাস") for forEach কোনও ফাংশন নয়

আমি Firefox 3-ব্যবহার করছি তাই আমি উভয় জানি getElementsByClassNameএবং Array.forEachউপস্থিত থাকে। এটি সূক্ষ্মভাবে কাজ করে:

[2, 5, 9].forEach( function(element, index, array) {
  //do stuff
});

getElementsByClassNameএকটি অ্যারের ফলাফল হয় ? যদি না হয়, এটা কি?

উত্তর:


384

না । ডিওএম ৪-তে উল্লিখিত হিসাবে এটি একটি HTMLCollection(আধুনিক ব্রাউজারগুলিতে, কমপক্ষে। পুরানো ব্রাউজারগুলি একটি ফিরে এসেছে NodeList)।

সমস্ত আধুনিক ব্রাউজারগুলিতে (অন্য কোনও আইই <= 8) তে আপনি অ্যারের forEachপদ্ধতিটিকে কল করতে পারেন , এটি উপাদান হিসাবে (এটি হোক HTMLCollectionবা NodeList) তালিকা হিসাবে পাস করে this:

var els = document.getElementsByClassName("myclass");

Array.prototype.forEach.call(els, function(el) {
    // Do stuff here
    console.log(el.tagName);
});

// Or
[].forEach.call(els, function (el) {...});

আপনি যদি ES6 ব্যবহার করতে সক্ষম হওয়ার খুশিতে রয়েছেন (যেমন আপনি নিরাপদে ইন্টারনেট এক্সপ্লোরারকে উপেক্ষা করতে পারেন বা আপনি কোনও ES5 ট্রান্সপোর্টার ব্যবহার করছেন), আপনি ব্যবহার করতে পারেন Array.from:

Array.from(els).forEach((el) => {
    // Do stuff here
    console.log(el.tagName);
});

29
প্রথমে এটিকে আরে রূপান্তর করার দরকার নেই। শুধু ব্যবহার [].forEach.call(elsArray, function () {...})
কে - এসই খারাপ 19

1
এটি কোনও নোডলিস্ট নয়। এটি একটি অ্যারের মতো অবজেক্ট। এমনকি আমি মনে করি না এটির কোনও উদাহরণ রয়েছে। querySelectorAllপদ্ধতি যদিও একটি নোডলিস্ট দেয়।
মাকসিম ভি।

2
@MaksimVi। আপনি একদম ঠিক বলছেন: DOM4 নির্দিষ্ট করে document.getElementsByClassName()একটি ফেরত পাঠাবেন HTMLCollection(যা অনুরূপ হলেও NodeList যায়)। ভুল উল্লেখ করার জন্য ধন্যবাদ।
টিম ডাউন

@ ম্যাক্সিমভি: আমি অবাক হই যে এটি কোনও এক সময় বদলেছে কিনা। আমি সাধারণত এই জিনিসগুলি পরীক্ষা করি।
টিম ডাউন

1
@TimDown, জন্য ধন্যবাদ HTMLCollectionডগা। এখন আমি শেষ পর্যন্ত HTMLCollection.prototype.forEach = Array.prototype.forEach;আমার কোড ব্যবহার করতে পারি।
মাকসিম ভি।

70

আপনি Array.fromসংগ্রহকে অ্যারেতে রূপান্তর করতে ব্যবহার করতে পারেন যা এটির চেয়ে পরিষ্কার Array.prototype.forEach.call:

Array.from(document.getElementsByClassName("myclass")).forEach(
    function(element, index, array) {
        // do stuff
    }
);

পুরানো ব্রাউজারগুলিতে যা সমর্থন করে না Array.from, আপনাকে বাবেলের মতো কিছু ব্যবহার করা দরকার।


ES6 এছাড়াও এই বাক্য গঠনটি যুক্ত করে:

[...document.getElementsByClassName("myclass")].forEach(
    (element, index, array) => {
        // do stuff
    }
);

...সমস্ত অ্যারের-মতো অবজেক্টগুলিতে কাজ করে বাকী বিন্যাসগুলি কেবল নিজেরাই সাজায় না, তবে মানগুলি থেকে অ্যারে তৈরি করতে ভাল পুরানো অ্যারে সিনট্যাক্স ব্যবহার করা হয়।


বিকল্প ফাংশন querySelectorAll(যা কিন্ডা getElementsByClassNameঅপ্রচলিত করে) এমন একটি সংগ্রহ প্রদান করে যা forEachমূলভাবে রয়েছে, অন্যান্য পদ্ধতি যেমন mapবা filterঅনুপস্থিত, তাই এই বাক্য গঠনটি এখনও কার্যকর:

[...document.querySelectorAll(".myclass")].map(
    (element, index, array) => {
        // do stuff
    }
);

[...document.querySelectorAll(".myclass")].map(element => element.innerHTML);

6
দ্রষ্টব্য: প্রস্তাবিত (বাবেল) হিসাবে স্থানান্তর না করে, এটি আই <এজ, অপেরা, সাফারি <9, অ্যান্ড্রয়েড ব্রাউজার, অ্যান্ড্রয়েডের জন্য ক্রোম, ... ইত্যাদিতে উপযুক্ত নয়) উত্স: মোজিলা দেব ডক্স
সান

30

অথবা আপনি নোডলিস্টটিquerySelectorAll ফেরত ব্যবহার করতে পারেন :

document.querySelectorAll('.myclass').forEach(...)

আধুনিক ব্রাউজারগুলি দ্বারা সমর্থিত (এজ সহ, তবে আইই নয়):
আমি কি ক্যোয়ারী নির্বাচন করতে পারি সমস্ত
নোডলিস্ট.প্রোটোটাইপ.ফোরেচ ()

MDN: ডকুমেন্ট.কোয়ারী নির্বাচনকারী সমস্ত ()


4
এলিমেন্টবাইক্লাসনামের চেয়ে পারফরম্যান্স পেনাল্টির কথা মনে রাখুন
পল

3
ডিওএম সংশোধন করার মতো আরও নিবিড় কাজের তুলনায় পারফরম্যান্স পেনাল্টি নগন্য । আমি যদি এর মধ্যে ,
000০,০০০কে

1
আপনি ভুল মাপদণ্ডটি যুক্ত করেছেন। এখানে সঠিক অন্যতম measurethat.net/Benchmarks/Show/4076/0/... শুধু আমার কম দামের ফোনে এটা দৌড়ে 160k পেয়েছিলাম / s বনাম 380k / সেকেন্ড। আপনি যেহেতু ডিওএম ম্যানিপুলেশনটির কথা উল্লেখ করেছেন, এখানে এটি খুব পরিমাপ হয় .net০/৩০ / বেঞ্চমার্কস / শো / 7070০৫/০৯/০৩০ কি / সে বনাম ১৩০ ক / সে। আপনি দেখতে পেয়েছেন যে এটি ডিওএম চালিত করতে আরও ধীর হয়েছে, সম্ভবত নোডলিস্ট স্থির হওয়ার কারণে (অন্যদের দ্বারা উল্লিখিত)। বেশিরভাগ ব্যবহারের ক্ষেত্রে এখনও অবহেলাযোগ্য তবে তবুও প্রায় 3 ভাঁজ ধীরে ধীরে।
স্যাজাবলস পল

14

সম্পাদনা: যদিও HTML এর নতুন সংস্করণে রিটার্নের ধরণটি পরিবর্তিত হয়েছে (টিম ডাউনের আপডেট হওয়া উত্তর দেখুন), নীচের কোডটি এখনও কাজ করে।

অন্যরা যেমন বলেছে, এটি নোডলিস্ট। এখানে একটি সম্পূর্ণ, কার্যকারী উদাহরণ যা আপনি চেষ্টা করতে পারেন:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <script>
            function findTheOddOnes()
            {
                var theOddOnes = document.getElementsByClassName("odd");
                for(var i=0; i<theOddOnes.length; i++)
                {
                    alert(theOddOnes[i].innerHTML);
                }
            }
        </script>
    </head>
    <body>
        <h1>getElementsByClassName Test</h1>
        <p class="odd">This is an odd para.</p>
        <p>This is an even para.</p>
        <p class="odd">This one is also odd.</p>
        <p>This one is not odd.</p>
        <form>
            <input type="button" value="Find the odd ones..." onclick="findTheOddOnes()">
        </form>
    </body>
</html>

এটি আইএন 9, এফএফ 5, সাফারি 5 এবং উইন 7 তে ক্রোম 12 এ কাজ করে।


9

এর ফলাফল getElementsByClassName()কোনও অ্যারে নয়, অ্যারের মতো বস্তু । বিশেষত এটিকে একটি বলা হয় HTMLCollection, এতে বিভ্রান্ত হওয়ার দরকার নেই NodeList( যার নিজস্ব forEach()পদ্ধতি রয়েছে )।

ES2015 এর সাথে একটি সহজ উপায় যা ব্যবহারের জন্য অ্যারে-জাতীয় বস্তুকে রূপান্তরিত করার জন্য Array.prototype.forEach()এখনও উল্লেখ করা হয়নি তা হ'ল স্প্রেড অপারেটর বা স্প্রেড সিনট্যাক্স ব্যবহার করা :

const elementsArray = document.getElementsByClassName('myclass');

[...elementsArray].forEach((element, index, array) => {
    // do something
});

2
আমি মনে করি এটি আধুনিক ব্রাউজারগুলিতে এটি করার সঠিক উপায়। এটি হ'ল সঠিক ক্ষেত্রে স্প্রেড সিনট্যাক্স সমাধানের জন্য তৈরি করা হয়েছিল।
ম্যাট করস্টোফ


3

যেমন ইতিমধ্যে বলা হয়েছে, getElementsByClassNameএকটি এইচটিএমএল সংগ্রহ সংগ্রহ করে , যা হিসাবে সংজ্ঞায়িত করা হয়

[Exposed=Window]
interface HTMLCollection {
  readonly attribute unsigned long length;
  getter Element? item(unsigned long index);
  getter Element? namedItem(DOMString name);
};

পূর্বে, কিছু ব্রাউজার পরিবর্তে একটি নোডলিস্ট ফিরিয়েছিল

[Exposed=Window]
interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable<Node>;
};

পার্থক্যটি গুরুত্বপূর্ণ, কারণ DOM4 এখন নোডলিস্টকে পুনরাবৃত্ত হিসাবে সংজ্ঞায়িত করে ।

ওয়েব আইডিএল খসড়া অনুসারে ,

একটি ইন্টারফেস বাস্তবায়নকারী অবজেক্টস যা মানগুলির ক্রম পাওয়ার জন্য পুনরাবৃত্তিযোগ্য সমর্থন হিসাবে পুনরাবৃত্তিযোগ্য হিসাবে ঘোষণা করা হয়।

দ্রষ্টব্য : ECMAScript ভাষা বাইন্ডিংয়ে, পুনরুক্তিযোগ্য একটি ইন্টারফেসের ইন্টারফেস প্রোটোটাইপ অবজেক্টে "এন্ট্রি", "forEach", "কী", "মান" এবং @@ পুনরাবৃত্তি বৈশিষ্ট্য থাকবে ।

তার মানে, আপনি ব্যবহার করতে চান তাহলে forEach, আপনি একটি DOM পদ্ধতি যা ফেরৎ ব্যবহার করতে পারেন NodeList মতো querySelectorAll

document.querySelectorAll(".myclass").forEach(function(element, index, array) {
  // do stuff
});

নোট করুন এটি এখনও ব্যাপকভাবে সমর্থিত নয়। নোড.চাইল্ডনোডের প্রতিটি পদ্ধতিও দেখুন ?


1
ক্রোম 49 ফিরেforEach in not a function
ভিটালি জেডনেভিচ

@ ভিটালিজেডানেভিচ ক্রোমিয়াম 50
ওরিওল

ক্রোম 50 এ আমি পাচ্ছিdocument.querySelectorAll(...).forEach is not a function
ভিটালি জেডনেভিচ

@VitalyZdanevich এটি Chromium 50 কাজ করি, আর এখনও ক্রোমিয়াম 53. হয়তো এটা না মনে করা হত স্থিতিশীল যথেষ্ট কাজ করে ক্রোম 50 প্রেরণ করা হবে
Oriol


1

এটি নিরাপদ উপায়:

var elements = document.getElementsByClassName("myclass");
for (var i = 0; i < elements.length; i++) myFunction(elements[i]);

0

getElementsByClassNameআয় HTMLCollection আধুনিক ব্রাউজারে।

যা অ্যারের মত আর্গুমেন্ট অনুরূপ বস্তু যা iteratable হয় for...ofলুপ নিচে কি দেখতে MDN ডক এটা সম্পর্কে বলার অপেক্ষা রাখে না হয়:

জন্য ... উপর iterable বস্তুর বিবৃতি একটি লুপ iterating সৃষ্টি সহ: বিল্ট ইন স্ট্রিং, অ্যারে, অ্যারে মত বস্তু (যেমন, আর্গুমেন্ট বা NodeList), TypedArray, মানচিত্র, সেট, এবং ব্যবহারকারী-সংজ্ঞায়িত iterables। এটি বস্তুর প্রতিটি স্বতন্ত্র সম্পত্তির মানটির জন্য কার্যকর করতে স্টেটমেন্ট সহ একটি কাস্টম পুনরাবৃত্তি হুককে অনুরোধ করে।

উদাহরণ

for (let element of getElementsByClassName("classname")){
   element.style.display="none";
}

না, না, টাইপ করা বিষয় অনুযায়ী:error TS2488: Type 'HTMLCollectionOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.
কচ্ছপ সুন্দর

@ টার্টলস অ্যারেকুট, এখানে ওপি জাভাস্ক্রিপ্ট ব্যবহার করছে টাইপস্ক্রিপ্ট নয় এবং আমি ভ্যানিলা জেএস সুপারিশ অনুযায়ী উত্তর দিয়েছি যাতে টাইপসক্রিপ্টে এটি সমস্যার বিভিন্ন সমাধান হতে পারে।
হরিসিংহ গোহিল

@ টার্টলস অ্যারিকিউট, উপায় দ্বারা এটি টাইপস্ক্রিপ্টেও কাজ করছে, তবে আপনাকে সঠিক ধরণের ভেরিয়েবল উল্লেখ করতে হবে যা নির্দিষ্ট সিএসএস শ্রেণীর উপাদান রাখে, সুতরাং এটি সেই অনুযায়ী এটি ছড়িয়ে দিতে পারে, বিশদভাবে উত্তরটি দেখুন দেখুন ।
হরিসিংহ গোহিল

0

এখানে আমি জেএসপিফায় তৈরি করেছি এমন একটি পরীক্ষা: https://jsperf.com/vanillajs-loop-through-elements-of-class

ক্রোম এবং ফায়ারফক্সের সর্বাধিক পারফরম্যান্ট সংস্করণ ডকুমেন্ট.জেট এলিমেন্টসওয়াই ক্লাসনামের সাথে একত্রে লুপের জন্য ভাল পুরানো:

var elements = document.getElementsByClassName('testClass'), elLength = elements.length;
for (var i = 0; i < elLength; i++) {
    elements.item(i).textContent = 'Tested';
};

সাফারিতে এই রূপটি বিজয়ী:

var elements = document.querySelectorAll('.testClass');
elements.forEach((element) => {
    element.textContent = 'Tested';
});

আপনি যদি সমস্ত ব্রাউজারগুলির জন্য সর্বাধিক সুগন্ধী বৈকল্পিক চান তবে এটি এটি হতে পারে:

var elements = document.getElementsByClassName('testClass');
Array.from(elements).map(
    (element) => {
        return element.textContent = 'Tested';
    }
);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.