এইচটিএমএল সংগ্রহের উপাদানগুলির জন্য লুপের জন্য


405

আমি একটিতে সমস্ত উপাদান আইডি পেতে সেট করার চেষ্টা করছি HTMLCollectionOf। আমি নিম্নলিখিত কোডটি লিখেছি:

var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {
    console.log(key.id);
}

তবে কনসোলে আমি নিম্নলিখিত ফলাফলটি পেয়েছি:

event1
undefined

যা আমি প্রত্যাশা করে তা নয়। দ্বিতীয় কনসোল আউটপুট কেন undefinedতবে প্রথম কনসোল আউটপুট হয় event1?


23
বিবৃতিতে ... প্রশ্নটি যখন শিরোনামটি "ফোরচ" বলে? গুগল করার সময় আমি দুর্ঘটনাক্রমে এখানে এসেছি।
mxt3

@ এমসিএটি 3 ঠিক আছে, আমার বুঝতে পেরে এটি জাভাতে প্রতিটি লুপের জন্য (একইভাবে কাজ করা) একটি উপমা ছিল।

1
@ এমএসটি 3 আমিও একই জিনিস ভেবেছিলাম! তবে গৃহীত উত্তরটি পড়ার পরে, আমি এই লাইনটি পেয়েছি, যা অ্যারে.ফ্রোম () ব্যবহার করে আমার ভবিষ্যদ্বাণী সমস্যার সমাধান করেছে:Array.from(document.getElementsByClassName("events")).forEach(function(item) {
হোল্ডঅফহঙ্গার

উত্তর:


839

মূল প্রশ্নের উত্তরে, আপনি for/inভুলভাবে ব্যবহার করছেন । আপনার কোড ইন, keyসূচক হয়। সুতরাং, সিউডো-অ্যারের থেকে মান পেতে, আপনাকে করতে হবেlist[key] এবং আইডি পেতে, আপনি করতেন list[key].id। তবে, আপনার এটি করা উচিত নয়for/in এটি প্রথম স্থানে ।

সংক্ষিপ্তসার (ডিসেম্বর 2018 এ যুক্ত)

কখনও ব্যবহার করবেন না for/inকোনও নোডলিস্ট বা এইচটিএমএল সংগ্রহের পুনরাবৃত্তি । এটি এড়ানোর কারণগুলি নীচে বর্ণনা করা হয়েছে।

আধুনিক ব্রাউজারগুলির সমস্ত সাম্প্রতিক সংস্করণ (সাফারি, ফায়ারফক্স, ক্রোম, এজ) for/ofডিওএম-তে সমস্ত সমর্থন পুনরাবৃত্তি যেমন সমর্থন করেnodeList বাHTMLCollection

এখানে একটি উদাহরণ:

var list = document.getElementsByClassName("events");
for (let item of list) {
    console.log(item.id);
}

পুরানো ব্রাউজারগুলি অন্তর্ভুক্ত করতে (আই.আই এর মতো জিনিসগুলি সহ), এটি সর্বত্র কাজ করবে:

var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
    console.log(list[i].id); //second console output
}

আপনার কেন ব্যবহার করা উচিত নয় এর ব্যাখ্যা for/in

for/inএকটি বস্তুর বৈশিষ্ট্য পুনরাবৃত্তি জন্য বোঝানো হয়। এর অর্থ এটি কোনও বস্তুর সমস্ত পুনরাবৃত্তিযোগ্য বৈশিষ্ট্য ফিরিয়ে দেবে। এটি কোনও অ্যারের জন্য কাজ করে প্রদর্শিত হতে পারে (অ্যারে উপাদানগুলি বা সিউডো-অ্যারে উপাদানগুলি ফেরত পাঠানোর জন্য), এটি বস্তুর অন্যান্য বৈশিষ্ট্যও ফিরিয়ে দিতে পারে যা আপনি অ্যারের-মতো উপাদানগুলির কাছ থেকে প্রত্যাশা করছেন তা নয়। এবং অনুমান করুন কী, কোনও HTMLCollectionবা nodeListঅবজেক্টের উভয়ই অন্যান্য বৈশিষ্ট্য থাকতে পারে যা for/inপুনরাবৃত্তি সহ ফিরে আসবে । আমি কেবল ক্রোমে এটি চেষ্টা করেছি এবং আপনি যেভাবে পুনরাবৃত্তি করছেন এটি পুনরুক্তি করা তালিকার আইটেমগুলি পুনরুদ্ধার করবে (সূচি 0, 1, 2, ইত্যাদি ...), তবে বৈশিষ্ট্য lengthএবং itemবৈশিষ্ট্যগুলি পুনরুদ্ধার করবে । for/inপুনরাবৃত্তির কেবল একটি HTMLCollection জন্য কাজ করবে না।


আপনি কেন এইচটিএমএল সংগ্রহের পুনরাবৃত্তি করতে পারবেন না তার জন্য http://jsfiddle.net/jender00/FzZ2H/ দেখুন for/in

ফায়ারফক্সে, আপনার for/inপুনরাবৃত্তি এই আইটেমগুলি ফেরত দেবে (বস্তুর সমস্ত পুনরাবৃত্তিযোগ্য বৈশিষ্ট্য):

0
1
2
item
namedItem
@@iterator
length

আশা করছি, এখন আপনি দেখতে কেন আপনি ব্যবহার করতে চান করতে পারেন for (var i = 0; i < list.length; i++)পরিবর্তে যাতে আপনি শুধু পেতে 0, 1এবং 2আপনার পুনরাবৃত্তির।


নীচে নীচে ব্রাউজারগুলি কীভাবে 2015-2018 সময়কালে আপনাকে পুনরাবৃত্তি করার অতিরিক্ত উপায় দেয় তার বিবর্তন ঘটেছে। আপনি উপরে বর্ণিত বিকল্পগুলি ব্যবহার করতে পারেন বলে আধুনিক ব্রাউজারগুলিতে এখন আরগুলির কোনওটির প্রয়োজন নেই।

2015 সালে ES6 এর জন্য আপডেট

ES6 এ যুক্ত করা হয়েছে Array.from()এটি একটি অ্যারের মতো কাঠামোটিকে আসল অ্যারেতে রূপান্তর করবে। এটি একজনকে সরাসরি এইভাবে একটি তালিকা গণনা করতে দেয়:

"use strict";

Array.from(document.getElementsByClassName("events")).forEach(function(item) {
   console.log(item.id);
});

ওয়ার্কিং ডেমো (ফায়ারফক্স, ক্রোম এবং এপ্রিল ২০১ 2016 হিসাবে প্রান্তে): https://jsfiddle.net/jfriend00/8ar4xn2s/


২০১S সালে ES6 এর জন্য আপডেট

আপনি এখন নিজের কোডটিতে এটি যুক্ত করে একটি NodeListএবং একটি দিয়ে নির্মাণের জন্য ES6 ব্যবহার করতে পারেন HTMLCollection:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

তারপরে, আপনি এটি করতে পারেন:

var list = document.getElementsByClassName("events");
for (var item of list) {
    console.log(item.id);
}

এটি ক্রোম, ফায়ারফক্স এবং এজের বর্তমান সংস্করণে কাজ করে। এটি কাজ করে কারণ এটি উভয় নোডলিস্ট এবং এইচটিএমএল সংগ্রহের প্রোটোটাইপগুলিতে অ্যারে পুনরুক্তকারী সংযুক্ত করে যাতে যখন তাদের / এর পুনরাবৃত্তি ঘটে তখন এটি পুনরাবৃত্ত করতে অ্যারে পুনরুক্তি ব্যবহার করে।

কার্যকারী ডেমো: http://jsfiddle.net/jender00/joy06u4e/


ডিসেম্বর 2016 এ ES6 এর জন্য দ্বিতীয় আপডেট

ডিসেম্বর 2016 হিসাবে, Symbol.iteratorসমর্থনটি Chrome v54 এবং ফায়ারফক্স ভি 50 এ অন্তর্নির্মিত হয়েছে সুতরাং নীচের কোডটি নিজেই কাজ করে। এটি এজের জন্য এখনও অন্তর্নির্মিত নয়।

var list = document.getElementsByClassName("events");
for (let item of list) {
    console.log(item.id);
}

ওয়ার্কিং ডেমো (ক্রোম এবং ফায়ারফক্সে): http://jsfiddle.net/jfriend00/3ddpz8sp/

ডিসেম্বর 2017 এ ES6 এর জন্য তৃতীয় আপডেট

ড 2017 এর হিসাবে, একটি জন্য এজ 41.16299.15.0 এই সামর্থ্য কাজ nodeListহিসেবে document.querySelectorAll(), কিন্তু না একটি HTMLCollectionহিসেবে document.getElementsByClassName()তাই আপনি নিজে পুনরুক্তিকারীর একটি জন্য এজ এটি ব্যবহার করতে দায়িত্ব অর্পণ করা HTMLCollection। তারা কেন সংগ্রহের প্রকারটি ঠিক করল, তা অন্যটি নয় তবে এটি সম্পূর্ণ রহস্য। তবে, আপনি এজ এর বর্তমান সংস্করণে কমপক্ষে document.querySelectorAll()ES6 for/ofসিনট্যাক্সের ফলাফলটি ব্যবহার করতে পারেন ।

আমি উপরের জেএসফিডেলটিকেও আপডেট করেছি যাতে এটি উভয় HTMLCollectionএবং nodeListপৃথক পৃথকভাবে পরীক্ষা করে এবং আউটপুটটি জেএসফিডালটিতেই ক্যাপচার করে।

মার্চ 2018 এ ES6 এর জন্য চতুর্থ আপডেট

তবে, সাফারিতেও সমর্থনটি Symbol.iteratorঅন্তর্নির্মিত হয়েছে, তাই আপনি for (let item of list)হয় document.getElementsByClassName()বা এর জন্য ব্যবহার করতে পারেনdocument.querySelectorAll()

এপ্রিল 2018 এ ES6 এর জন্য পঞ্চম আপডেট

স্পষ্টতই, এর HTMLCollectionসাথে পুনরাবৃত্তি করার জন্য সমর্থন for/of2018 এর পাতায় एज 18 এ আসবে।

নভেম্বর 2018 এ ES6 এর ষষ্ঠ আপডেট

আমি নিশ্চিত করতে পারি যে মাইক্রোসফ্ট এজ ভি 18 এর সাথে (এটি ফলস 2018 উইন্ডোজ আপডেটের অন্তর্ভুক্ত), আপনি এখন একটি এজেএল এইচটিএমএল সংগ্রহ এবং একটি নোডলিস্ট উভয়ই পুনরাবৃত্তি করতে পারেন /

সুতরাং, এখন সমস্ত আধুনিক ব্রাউজারগুলিতে for/ofএইচটিএমএল সংগ্রহ এবং নোডলিস্ট উভয় বস্তুর পুনরাবৃত্তির জন্য স্থানীয় সমর্থন রয়েছে ।


1
জেএস আপডেট হওয়ায় খুব বিস্তারিত আপডেটের জন্য আপনাকে ধন্যবাদ। এটি প্রাথমিকভাবে অন্য নির্দিষ্ট নিবন্ধ / পোস্টের প্রসঙ্গে এই পরামর্শটি বুঝতে সহায়তা করে যা কেবলমাত্র একটি নির্দিষ্ট জেএস রিলিজের ক্ষেত্রে প্রযোজ্য।
brownmagik352

অসামান্য উত্তর, আশ্চর্যজনক আপডেট সমর্থন .. ধন্যবাদ।
cossacksman

79

আপনি ব্যবহার করতে পারবেন না for/ inউপর NodeLists অথবা HTMLCollectionসে। যাইহোক, যদি আপনি কিছু ব্যবহার করতে পারেন Array.prototypeপদ্ধতি, যতদিন আপনি .call()তাদের এবং মধ্যে পাস NodeListবা HTMLCollectionযেমন this

সুতরাং নীচে jPress00 এর forলুপের বিকল্প হিসাবে বিবেচনা করুন :

var list= document.getElementsByClassName("events");
[].forEach.call(list, function(el) {
    console.log(el.id);
});

এমডিএন সম্পর্কে একটি ভাল নিবন্ধ রয়েছে যা এই কৌশলটি কভার করে। ব্রাউজারের সামঞ্জস্যতা সম্পর্কে তাদের সতর্কতা নোট করুন:

[...] একটি স্থানীয় পদ্ধতি NodeListহিসাবে যেমন একটি হোস্ট অবজেক্ট (যেমন ) পাস করা সমস্ত ব্রাউজারে কাজ করার গ্যারান্টিযুক্ত নয় এবং এটি কিছুতে ব্যর্থ বলে জানা যায়।thisforEach

সুতরাং এই পদ্ধতির সুবিধাজনক হওয়ার সময় একটি forলুপটি সর্বাধিক ব্রাউজারের সাথে সামঞ্জস্যপূর্ণ সমাধান হতে পারে।

আপডেট (আগস্ট 30, 2014): অবশেষে আপনি ES6 for/of ব্যবহার করতে সক্ষম হবেন !

var list = document.getElementsByClassName("events");
for (const el of list)
  console.log(el.id);

এটি ইতিমধ্যে Chrome এবং ফায়ারফক্সের সাম্প্রতিক সংস্করণগুলিতে সমর্থিত।


1
খুব সুন্দর! আমি এই কৌশলটি ব্যবহার করেছি একটি থেকে নির্বাচিত বিকল্পগুলির মান পেতে <select multiple>। উদাহরণ:[].map.call(multiSelect.selectedOptions, function(option) { return option.value; })
XåpplI'-I0llwlg'I -

1
আমি এটির জন্য একটি ES2015 সমাধান খুঁজছিলাম, সুতরাং for ... ofকাজটি নিশ্চিত করার জন্য ধন্যবাদ ।
রিচার্ড টার্নার

60

ES6 এ, আপনি যেমন কিছু করতে পারেন [...collection], বা Array.from(collection),

let someCollection = document.querySelectorAll(someSelector)
[...someCollection].forEach(someFn) 
//or
Array.from(collection).forEach(someFn)

যেমন: -

    navDoms = document.getElementsByClassName('nav-container');
    Array.from(navDoms).forEach(function(navDom){
     //implement function operations
    });

@ ড্যানিয়েলম অনুমান করুন যে আমি যা করেছি তা হ'ল অগভীর একটি অ্যারের মতো কাঠামোটি তৈরি করুন
মিডো

আমি দেখছি, ধন্যবাদ - এখন আমি যে ডকুমেন্টেশনটি সন্ধান করছিলাম তা পেয়েছি: developer.mozilla.org/en/docs/Web/
জাভা স্ক্রিপ্ট

আমি এটিকে সবসময়ই ব্যবহার করি, অ্যারে.ফর্মের চেয়ে চোখের কাছে আরও সহজ, আমি ভাবছি যদি এটির যথেষ্ট কর্মক্ষমতা বা স্মৃতিশক্তি রয়েছে bac উদাহরণস্বরূপ যদি আমাকে কোনও টেবিল সারির ঘরগুলি পুনরাবৃত্তি করতে হয় তবে আমি এটি করার [...row.cells].forEachপরিবর্তে একটি ব্যবহার করিrow.querySelectorAll('td')
মোজিমি

16

আপনি এই দুটি লাইন যুক্ত করতে পারেন:

HTMLCollection.prototype.forEach = Array.prototype.forEach;
NodeList.prototype.forEach = Array.prototype.forEach;

এইচটিএমএল সংকলন getElementsByClassName এবং getElementsByTagName দ্বারা ফিরে আসে

নোডলিস্ট ক্যোয়ারী নির্বাচনকারী সমস্ত দ্বারা ফিরে আসে return

এই মত আপনি প্রতিটি জন্য একটি করতে পারেন:

var selections = document.getElementsByClassName('myClass');

/* alternative :
var selections = document.querySelectorAll('.myClass');
*/

selections.forEach(function(element, i){
//do your stuffs
});

এই উত্তরটি এত কার্যকর বলে মনে হচ্ছে। ধরাটা কী?
পেহেজে

2
ক্যাচটি হ'ল এই সমাধানটি আই 11 এ কাজ করে না! ভাল সমাধান যদিও।
রাহুল গাবা


7

আইই ১১ এবং এও forEach ব্যবহার করতে আমার সমস্যা হয়েছিল ফায়ারফক্স ৪৯-

আমি এই মত একটি workaround খুঁজে পেয়েছি

Array.prototype.slice.call(document.getElementsByClassName("events")).forEach(function (key) {
        console.log(key.id);
    }

আইই 11 এর জন্য দুর্দান্ত সমাধান! একটি সাধারণ কৌশল হিসাবে ব্যবহৃত
হত

6

বিকল্প Array.fromব্যবহার করা হয়Array.prototype.forEach.call

প্রতিটির জন্য, প্রত্যেকটির জন্য: Array.prototype.forEach.call(htmlCollection, i => { console.log(i) });

মানচিত্র: Array.prototype.map.call(htmlCollection, i => { console.log(i) });

ect, ...


6

forলুপিং থেকে বাঁচতে এস 6 বৈশিষ্ট্যগুলি ব্যবহার করার কোনও কারণ নেই যদি আপনি আইই 9 বা তার বেশি থাকেন।

ইএস 5 এ দুটি ভাল বিকল্প রয়েছে। প্রথমত, আপনি "ধার" করতে পারেন Array'গুলি forEachযেমন ইভান উল্লেখ

তবে আরও ভাল ...

ব্যবহারের Object.keys(), যা নেই আছে forEachএবং "নিজের বৈশিষ্ট্য" স্বয়ংক্রিয়ভাবে ফিল্টার।

এটি হ'ল Object.keysএকটি for... inসাথে একটি করার সমতুল্য HasOwnProperty, তবে এটি অনেক মসৃণ।

var eventNodes = document.getElementsByClassName("events");
Object.keys(eventNodes).forEach(function (key) {
    console.log(eventNodes[key].id);
});

5

মার্চ ২০১ 2016, ক্রোম 49.0 এ, এর for...ofজন্য কাজ করে HTMLCollection:

this.headers = this.getElementsByTagName("header");

for (var header of this.headers) {
    console.log(header); 
}

দেখুন এখানে ডকুমেন্টেশন

তবে এটি কেবল তখনই কাজ করে যদি আপনি নিম্নলিখিতটি ব্যবহারের আগে নিম্নরূপ প্রয়োগ করেন for...of:

HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

একই ব্যবহার করার জন্য প্রয়োজনীয় for...ofসঙ্গে NodeList:

NamedNodeMap.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

আমি বিশ্বাস করি / আশা করি for...ofখুব শীঘ্রই উপরের কাজটি ছাড়াই কাজ করবে। উন্মুক্ত সমস্যাটি এখানে:

https://bugs.chromium.org/p/chromium/issues/detail?id=401699

আপডেট: নীচে এক্সপেনজরের মন্তব্য দেখুন: এটি এপ্রিল ২০১ of হিসাবে ঠিক করা হয়েছে You আপনাকে এইচটিএমএল কোলকশন.প্রোটোটাইপ [সিম্বল.াইটেটর] = অ্যারে.প্রোটোটাইপ [সিম্বল.াইটেটর] যোগ করার দরকার নেই; এর ... এর সাথে এইচটিএমএল সংগ্রহের মাধ্যমে পুনরাবৃত্তি করতে


4
এই এপ্রিল 2016. এর হিসাবে যুক্ত করার প্রয়োজন হবে না সংশোধন করা হয়েছে HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];একটি পুনরুক্তি উপর HTMLCollectionদিয়ে for...of
এক্সপেনজর


2

আমি সর্বদা ব্যবহার করি এমন সহজ কাজ ound

let list = document.getElementsByClassName("events");
let listArr = Array.from(list)

এর পরে আপনি কোনও পছন্দসই অ্যারে পদ্ধতি নির্বাচন করতে পারবেন run

listArr.map(item => console.log(item.id))
listArr.forEach(item => console.log(item.id))
listArr.reverse()

1

আপনি যদি ES এর পুরানো সংস্করণগুলি ব্যবহার করেন (উদাহরণস্বরূপ ES5), আপনি ব্যবহার করতে পারেন as any:

for (let element of elementsToIterate as any) {
      console.log(element);
}

0

আপনি এটিতে পরিবর্তন করতে চান

var list= document.getElementsByClassName("events");
console.log(list[0].id); //first console output
for (key in list){
    console.log(list[key].id); //second console output
}

5
এফওয়াইআই, কেন এটি সঠিকভাবে কাজ করবে না তার জন্য আমার উত্তর দেখুন। for (key in list)বিভিন্ন বৈশিষ্ট্য ফিরে আসবে HTMLCollectionযে সংগ্রহে আইটেম হতে বোঝানো হয় না।
jਫਰ00
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.