নডলিস্টের জন্য কেন নেই?


91

আমি <abbr>উপাদানগুলির অভ্যন্তরীণ পাঠ্য পরিবর্তন করতে একটি শর্ট স্ক্রিপ্টে কাজ করছিলাম , তবে nodelistএটির কোনও forEachপদ্ধতি নেই found আমি জানি যে nodelistউত্তরাধিকারসূত্রে আসে না Array, তবে মনে হয় না যে এটি forEachএকটি দরকারী পদ্ধতি হবে? কোনও বাস্তবায়ন সমস্যা আছে যা সম্পর্কে আমি সচেতন নই যা যুক্ত forEachহওয়া রোধ করে nodelist?

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


উত্তর:


94

নোডলিস্টে এখন সমস্ত বড় ব্রাউজারে প্রতিটি () জন্য রয়েছে

দেখুন nodeList foreach () MDN উপর

আসল উত্তর

এই উত্তরগুলির মধ্যে কোনওটিই ব্যাখ্যা করে না যে কেন নোডলিস্ট অ্যারে থেকে উত্তরাধিকার সূত্রে আসে না, এভাবে এটি থাকার অনুমতি দেয় forEachএবং বাকী সমস্তই।

উত্তরটি এই এসএস-আলোচনা থ্রেডে পাওয়া যায় । সংক্ষেপে, এটি ওয়েবটি ভেঙে দেয়:

সমস্যাটি কোডটি ছিল যা ভুলভাবে উদাহরণস্বরূপ ধরে নিয়েছিল যে উদাহরণটি অ্যারে.প্রোটোটাইপ.কনক্যাটের সাথে মিশে একটি অ্যারে ছিল।

গুগলের ক্লোজার লাইব্রেরিতে একটি বাগ ছিল যার কারণে প্রায় সমস্ত গুগলের অ্যাপ্লিকেশন ব্যর্থ হয়েছিল to এটি খুঁজে পাওয়ার সাথে সাথে লাইব্রেরিটি আপডেট করা হয়েছিল তবে এখনও সেখানে কোড থাকতে পারে যা কনকটের সাথে একই ভুল অনুমানটি তৈরি করে।

যে, কিছু কোড কিছু ভালো লেগেছে

if (x instanceof Array) {
  otherArray.concat(x);
} else {
  doSomethingElseWith(x);
}

যাইহোক, concat"রিয়েল" অ্যারেগুলি (অ্যারে উদাহরণস্বরূপ নয়) অন্যান্য অবজেক্টের থেকে আলাদা আচরণ করবে:

[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat(4) // [1, 2, 3, 4]

সুতরাং এর মানে হল যে xনোডলিস্টের সময় উপরের কোডটি ভেঙে গেছে, কারণ এটি doSomethingElseWith(x)পথে নেমে যাওয়ার আগে , যখন পরে এটি otherArray.concat(x)পথে নেমে গিয়েছিল , যা xসত্যিকারের অ্যারে না থেকে অদ্ভুত কিছু করেছিল ।

কিছু সময়ের জন্য একটি Elementsশ্রেণীর জন্য প্রস্তাব ছিল যা অ্যারের প্রকৃত উপক্লাস ছিল এবং এটি "নতুন নোডলিস্ট" হিসাবে ব্যবহৃত হবে। তবে, এটি কমপক্ষে আপাতত DOM স্ট্যান্ডার্ড থেকে সরানো হয়েছে , কারণ বিভিন্ন প্রযুক্তিগত এবং নির্দিষ্টকরণ সংক্রান্ত বিভিন্ন কারণে এটি এখনও কার্যকর করা সম্ভব ছিল না।


11
আমার কাছে খারাপ কল বলে মনে হচ্ছে। গুরুতরভাবে, আমি মনে করি এটি একবারে জিনিসগুলি ভাঙ্গার সঠিক সিদ্ধান্ত, বিশেষত যদি এর অর্থ আমাদের ভবিষ্যতের জন্য বুদ্ধিমান এপিআই রয়েছে। এছাড়াও, এটি ওয়েবের মতো স্থিতিশীল প্ল্যাটফর্মের মতো নয়, লোকেরা তাদের 2 বছরের পুরানো জাভাস্ক্রিপ্টটি প্রত্যাশার মতো আর কাজ করে না ..
JialToTheWorld

4
"ওয়েবে ব্রেক"! = "গুগল
ম্যাট

কেন কেবল অ্যারে.প্রোটোটাইপ থেকে প্রতিটি পদ্ধতি ফরোন করবেন না? উদাহরণস্বরূপ, অ্যারে প্রোটোটাইপ হিসাবে যুক্ত করার পরিবর্তে, কেবল এইটি করুন for
পপ কার্নেল

4
বিঃদ্রঃ; এই আপডেটটি NodeList now has forEach() in all major browsersথেকে বোঝা যাচ্ছে যে IE কোনও প্রধান ব্রাউজার নয়। আশা করি এটি কিছু লোকের পক্ষে সত্য তবে এটি আমার পক্ষে সত্য নয় (এখনও)।
গ্রাহাম পি হিথ

58

আপনি করতে পারেন

Array.prototype.forEach.call (nodeList, function (node) {

    // Your code here.

} );

4
Array.prototype.forEach.callএতে সংক্ষিপ্ত হতে পারে[].forEach.call
কোডব্রায়ার

7
@ কোডবেউর: এটি কেবল ছোট করা নয় Array.prototype.forEach.call, এটি একটি খালি অ্যারে তৈরি করছে এবং এর forEachপদ্ধতিটি ব্যবহার করছে ।
পল ডি ওয়েট

34

আপনি নোডের একটি নতুন অ্যারে তৈরি বিবেচনা করতে পারেন।

  var nodeList = document.getElementsByTagName('div'),

      nodes = Array.prototype.slice.call(nodeList,0); 

  // nodes is an array now.
  nodes.forEach(function(node){ 

       // do your stuff here.  

  });

দ্রষ্টব্য: এটি আমরা এখানে তৈরি করছি নোড রেফারেন্সগুলির একটি তালিকা / অ্যারে, কোনও সদৃশ নোড নেই।

  nodes[0] === nodeList[0] // will be true

22
বা শুধু করুন Array.prototype.forEach.call(nodeList, fun)
akuhn

আমিও foreach ফাংশন যেমন যে aliasing সুপারিশ করবে: var forEach = Array.prototype.forEach.call(nodeList, callback);। এখন আপনি কেবল কল করতে পারেনforEach(nodeList, callback);
অ্যান্ড্রু ক্র্যাসওয়েল

19

কখনও বলবেন না, এটি 2016 এবং NodeListঅবজেক্টটি forEachসর্বশেষ ক্রোমে একটি পদ্ধতি প্রয়োগ করেছে (v52.0.2743.116)।

এটি অন্য উত্পাদনকারী হিসাবে এটি এখনও ব্যবহার করা খুব তাড়াতাড়ি যেমন অন্যান্য ব্রাউজার এটি সমর্থন করে না (পরীক্ষিত এফএফ 49) তবে আমি অনুমান করব যে এটি শীঘ্রই মানক করা হবে।


4
অপেরাও এটিকে সমর্থন করে এবং ফায়ারফক্সের ভি 50 এ সমর্থন যুক্ত হবে, 15/11/16 তারিখে প্রকাশের জন্য নির্ধারিত।
শেগি

4
বাস্তবায়িত হলেও এটি কোনও মানের অংশ নয়। এটি Array.prototype.slice.call(nodelist).forEach(…)স্ট্যান্ডার্ড এবং পুরানো ব্রাউজারগুলিতে কাজ করে এমনটি করা এখনও সেরা ।
নাট

17

সংক্ষেপে, এটি সেই পদ্ধতিটি বাস্তবায়নের জন্য একটি ডিজাইনের বিরোধ।

এমডিএন থেকে:

আমি কেন নোডলিস্টে প্রতিটি বা মানচিত্র ব্যবহার করতে পারি না?

নোডলিস্ট অ্যারেগুলির মতো খুব বেশি ব্যবহৃত হয় এবং এটিতে অ্যারে.প্রোটোটাইপ পদ্ধতি ব্যবহার করা লোভনীয় হবে। এটি অবশ্য অসম্ভব।

প্রোটোটাইপের উপর ভিত্তি করে জাভাস্ক্রিপ্টের একটি উত্তরাধিকার ব্যবস্থা রয়েছে। অ্যারের উদাহরণগুলি অ্যারে পদ্ধতিগুলি (যেমন ফোরইচ বা মানচিত্রের মতো) উত্তরাধিকার সূত্রে প্রাপ্ত হয় কারণ তাদের প্রোটোটাইপ শৃঙ্খলে নিম্নলিখিতগুলির মতো দেখায়:

myArray --> Array.prototype --> Object.prototype --> null (কোনও বস্তুর প্রোটোটাইপ চেইন বেশ কয়েকবার অবজেক্ট.জেটপ্রোটোটাইপফাকে কল করে পাওয়া যাবে)

জন্য প্রতিটি, মানচিত্র এবং পছন্দগুলি অ্যারে.প্রোটোটাইপ অবজেক্টের নিজস্ব বৈশিষ্ট্য।

অ্যারেগুলির বিপরীতে, নোডলিস্ট প্রোটোটাইপ শৃঙ্খলে নিম্নলিখিতগুলির মতো দেখায়:

myNodeList --> NodeList.prototype --> Object.prototype --> null

নোডলিস্ট.প্রোটোটাইপটিতে আইটেম পদ্ধতি রয়েছে তবে অ্যারে.প্রোটোটাইপ পদ্ধতিগুলির কোনওটিই নেই, সুতরাং সেগুলি নোডলিস্টে ব্যবহার করা যায় না।

উত্স: https://developer.mozilla.org/en-US/docs/DOM/NodeList ( আমি কেন নোডলিস্টে প্রতিটি বা মানচিত্র ব্যবহার করতে পারি না? এখানে স্ক্রোল করুন )


8
সুতরাং, যেহেতু এটি একটি তালিকা, কেন এটি সেভাবে ডিজাইন করা হয়েছে? কি তাদের জন্য চেইন বাঁধন ছিল: myNodeList --> NodeList.prototype --> Array.prototype --> Object.prototype --> null?
ইগর প্যানটোভিć

14

আপনি যদি নোডলিস্টে প্রতিটি জন্য ব্যবহার করতে চান তবে অ্যারে থেকে কেবল সেই ফাংশনটি অনুলিপি করুন:

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

সর্বোপরি, এখন আপনি এটিকে একইভাবে ব্যবহার করতে পারবেন আপনি অ্যারের জন্য:

document.querySelectorAll('td').forEach(function(o){
   o.innerHTML = 'text';
});

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

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

4
এখন যে নোডলিস্ট.এফ প্রতিটি বিদ্যমান, এটি একটি হাস্যকরভাবে সরল পলফিল হয়ে ওঠে!
দামন

7

ES2015 এ, আপনি এখন forEachনোডলিস্টে পদ্ধতি ব্যবহার করতে পারেন ।

document.querySelectorAll('abbr').forEach( el => console.log(el));

দেখুন MDN লিংক

তবে আপনি যদি এসএসটি ২০১৫ এ এইচটিএমএল সংগ্রহ বা অন্যান্য অ্যারের মতো অবজেক্ট ব্যবহার করতে চান তবে আপনি Array.from()পদ্ধতিটি ব্যবহার করতে পারেন । এই পদ্ধতিটি একটি অ্যারের মতো বা পুনরাবৃত্তিযোগ্য অবজেক্ট নেয় (নোডলিস্ট, এইচটিএমএল সংগ্রহ, স্ট্রিং ইত্যাদি সহ) এবং একটি নতুন অ্যারের উদাহরণ প্রদান করে। আপনি এটি এর মতো ব্যবহার করতে পারেন:

const elements = document.getElementsByTagName('abbr');
Array.from(elements).forEach( el => console.log(el));

যেহেতু Array.from()পদ্ধতিটি শিথিলযোগ্য, আপনি এটি এসএস কোডে এটি ব্যবহার করতে পারেন

var elements = document.getElementsByTagName('abbr');
Array.from(elements).forEach( function(el) {
    console.log(el);
});

বিশদগুলির জন্য, MDN পৃষ্ঠাটি দেখুন।

বর্তমান ব্রাউজার সমর্থন পরীক্ষা করতে ।

বা

আরেকটি এস -2015 উপায় হ'ল স্প্রেড অপারেটর ব্যবহার করা।

[...document.querySelectorAll('abbr')].forEach( el => console.log(el));

এমডিএন স্প্রেড অপারেটর

স্প্রেড অপারেটর - ব্রাউজার সমর্থন


2

আমার সমাধান:

//foreach for nodeList
NodeList.prototype.forEach = Array.prototype.forEach;
//foreach for HTML collection(getElementsByClassName etc.)
HTMLCollection.prototype.forEach = Array.prototype.forEach;

4
প্রোটোটাইপগুলির মাধ্যমে, বিশেষত আইই ( প্রবন্ধ ) এর পুরানো সংস্করণগুলিতে DOM এর কার্যকারিতা বাড়ানো প্রায়শই ভাল ধারণা নয় ।
কেএফই

0

নোডলিস্টটি ডিওএম এপিআইয়ের অংশ। ECMAScript বাইন্ডিংগুলি দেখুন যা জাভাস্ক্রিপ্টেও প্রযোজ্য। http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html । নোডলিস্ট এবং একটি পঠনযোগ্য দৈর্ঘ্যের সম্পত্তি এবং আইটেম (সূচক) ফাংশন একটি নোড ফেরত।

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


তবে এটি বাস্তবায়ন করা উচিত হবে না এমন কোনও কারণ আছে কি? JQuery এবং ডোজো উভয়ই এটি তাদের নিজস্ব লাইব্রেরিতে
সাপ এবং কফি

4
তবে এটি কীভাবে ডিজাইনের দ্বন্দ্ব?
সাপ এবং কফি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.