কীভাবে জাভাস্ক্রিপ্টে একটি ডিওএম নোড তালিকাটিকে একটি অ্যারে রূপান্তর করবেন?


101

আমার একটি জাভাস্ক্রিপ্ট ফাংশন রয়েছে যা এইচটিএমএল নোডগুলির একটি তালিকা গ্রহণ করে তবে এটি জাভাস্ক্রিপ্ট অ্যারের প্রত্যাশা করে (এটি এতে কিছু অ্যারে পদ্ধতি চালায়) এবং আমি এটিকে Document.getElementsByTagNameডিওএম নোড তালিকার রিটার্নটি প্রদান করতে চাই।

প্রথমদিকে আমি সাধারণ কিছু ব্যবহার করার কথা ভেবেছিলাম:

Array.prototype.slice.call(list,0)

এবং এটি সমস্ত ব্রাউজারগুলিতে সূক্ষ্মভাবে কাজ করে, অবশ্যই ইন্টারনেট এক্সপ্লোরার যা "জেএসক্রিপ্টের প্রত্যাশিত প্রত্যাশিত ত্রুটি" ত্রুটি প্রদান করে, স্পষ্টতই Document.getElement*পদ্ধতি দ্বারা ফিরিয়ে দেওয়া ডোম নোড তালিকা কোনও ফাংশন কলের লক্ষ্য হিসাবে পর্যাপ্ত জাস্ক্রিপ্ট অবজেক্ট নয়।

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

আমার শেষ খাদের প্রচেষ্টা ডম নোড তালিকার উপরে পুনরাবৃত্তি হওয়া এবং নিজেই একটি অ্যারে তৈরি করা, তবে এটি করার কোনও সুন্দর উপায় আছে?


আরও ভাল, ডিওএম নোড তালিকা থেকে রূপান্তর করতে একটি ফাংশন তৈরি করুন, তবে এটি আমার সমাধান হতে পারে, আমি মনে করি আপনি এটি সঠিক পেয়েছেন।
ক্রিস্টোফার সল-স্টোরগার্ড

> এর জন্য (i = 0; i & lt; x.length; i ++) কেন প্রতিটি পুনরাবৃত্তিতে নোডলিস্টের দৈর্ঘ্য পাবেন? এটি কেবল সময়ের অপচয় নয়, যেহেতু নোডলিস্টগুলি লাইভ সংগ্রহ, লুপের শরীরে কোনও কিছু যদি তার দৈর্ঘ্য পরিবর্তন করে, আপনি অবিরাম লুপ করতে পারেন বা সীমার বাইরে সীমানা মারতে পারেন। পরেরটি সবচেয়ে খারাপ যেটি ঘটতে পারে যদি আপনি দৈর্ঘ্যটিকে একটি ভেরিয়েবলকে অর্পণ করেন এবং একটি ত্রুটি একটি অন্তহীন লুপের চেয়ে অনেক ভাল।

এটি একটি সত্যই পুরানো প্রশ্ন, তবে jQuery নির্দিষ্টভাবে .noConflict পদ্ধতিতে তৈরি করা হয়েছিল যাতে এটি অন্যান্য গ্রন্থাগারগুলির সাথে (এমনকি নিজেই) দ্বন্দ্ব সৃষ্টি না করে, মানে jQuery এর একাধিক সংস্করণ কোনও পৃষ্ঠায় লোড করা যায়। এটি বলেছে, কোনও গ্রন্থাগার ব্যবহার / লোড করা এড়ানো ভাল best
ভোলআরন

@ ভোলআরন: দ্রুত ২০১ 2016-তে এগিয়ে যাওয়া এবং প্রত্যেকে জাভাস্ক্রিপ্ট লাইব্রেরি পৃষ্ঠাতে যে আকার যুক্ত করবে সে সম্পর্কে এখনও উত্সাহী। মঞ্জুর, jQuery minified এবং gzipped, 30KB তার এখনও 30KB অত্যধিক মাত্র একটি নোড তালিকা রুপান্তর :-)
গাস

উত্তর:


68

নোডলিস্ট হোস্ট অবজেক্টস , হোস্ট অবজেক্টগুলিতেArray.prototype.slice মেথড ব্যবহার করে কাজ করার গ্যারান্টি নেই, ইসিমাস্ক্রিপ্ট স্পেসিফিকেশন বলে:

স্লাইস ফাংশনটি কোনও হোস্ট অবজেক্টে সফলভাবে প্রয়োগ করা যায় কিনা তা বাস্তবায়ন নির্ভর।

আমি আপনাকে পুনরাবৃত্তি NodeListএবং একটি অ্যারে প্রতিটি বিদ্যমান উপাদান যোগ করার জন্য একটি সহজ ফাংশন করতে সুপারিশ করব :

function toArray(obj) {
  var array = [];
  // iterate backwards ensuring that length is an UInt32
  for (var i = obj.length >>> 0; i--;) { 
    array[i] = obj[i];
  }
  return array;
}

হালনাগাদ:

অন্যান্য উত্তরগুলির পরামর্শ অনুসারে, আপনি এখন আধুনিক পরিবেশে স্প্রেড সিনট্যাক্স বা Array.fromপদ্ধতিটি ব্যবহার করতে পারেন :

const array = [ ...nodeList ] // or Array.from(nodeList)

তবে এটি সম্পর্কে চিন্তা করেই, আমি অনুমান করি যে নোডলিস্টকে একটি অ্যারেতে রূপান্তর করার জন্য সবচেয়ে সাধারণ ব্যবহারের কেসটি এটির পুনরাবৃত্তি হয় এবং এখন NodeList.prototypeঅবজেক্টটির forEachস্থানীয়ভাবে পদ্ধতি রয়েছে , তাই আপনি যদি আধুনিক পরিবেশে থাকেন তবে আপনি সরাসরি এটি ব্যবহার করতে পারেন, বা থাকতে পারেন একটি পলিফিল


4
এটি তালিকার মূল ক্রমটি বিপরীত করে একটি অ্যারে তৈরি করছে, যা আমি মনে করি না যে ওপি কী চায়। আপনি কি array[i] = obj[i]পরিবর্তে করতে চেয়েছিলেন array.push(obj[i])?
টিম ডাউন

@ টিম, ঠিক আছে, আমার এটি আগের মতোই ছিল তবে গতকাল রাতে এটি লক্ষ্য করা ছাড়াই সম্পাদিত হয়েছিল (স্থানীয় সময় সকাল AM টা) :), ধন্যবাদ!
খ্রিস্টান সি সালভাডা

9
কোন পরিস্থিতিতে obj.lengthপূর্ণসংখ্যার মান ছাড়া অন্য কিছু হতে পারে?
পিটার

4
আমি বিশ্বাস করতে পারি না যে এটি এত জটিল। কুৎসিত। এটি ওয়েব / জেএস প্রোগ্রামিংয়ের খুব সাধারণ প্রয়োজন। ভাষার পরবর্তী প্রকাশের জন্য একটি নতুন পদ্ধতি?
অ্যান্ড্রু কোপার

4
@ আলবার্তো পেরেজ, আপনাকে স্বাগতম! সালুদোসের হস্তা মাদ্রিদ!
খ্রিস্টান সি সালভাডা

132

এস 6 এ আপনি নীচের মত ব্যবহার করতে পারেন:

  • স্প্রেড অপারেটর

     var elements = [... nodelist]
    
  • ব্যবহার Array.from

     var elements = Array.from(nodelist)
    

https://developer.mozilla.org/en-US/docs/Web/API/NodeList এ আরও রেফারেন্স


4
এর সাথে এত সহজ Array.from(): ডি
জোসান ইরচেইটা

4
যদি কেউ এই পদ্ধতিটি টাইপস্ক্রিপ্ট (ES5- এ) ব্যবহার করে তবে কেবল Array.fromকাজ করে, কারণ টিএস এটিতে স্থানান্তর করে nodelist.slice- যা সমর্থিত নয়।
পিটার আলবার্ট

আমি আপনার এক বছর আগে একই উত্তর দিয়েছি এবং আপনি আমাকে ভোটে পাস করেছেন? আমি এটি ব্যাখ্যা করতে পারি না ..
vsync

4
@ ভিসিঙ্ক, আপনার উত্তরটির উল্লেখ নেইArray.from
ইএসআর

@ এডমন্ডআরিড - তাই? কীভাবে এটি ন্যায়সঙ্গত হয়। এটি সত্যিকারের অধিবেশনায় এত বেশি লেখার জন্য এটি আর ব্যবহার করা হবে না, কেবল spreadব্যবহৃত হবে।
vsync

17

স্প্রেড (ES2015) ব্যবহার করে , এটি এতটা সহজ:[...document.querySelectorAll('p')]

( alচ্ছিক : উপরের ES6 কোডটি ES5 সিনট্যাক্সে স্থানান্তর করতে বাবেল ব্যবহার করুন )


আপনার ব্রাউজারের কনসোলে এটি ব্যবহার করে দেখুন এবং যাদুটি দেখুন:

for( links of [...document.links] )
  console.log(links);

কমপক্ষে সর্বশেষতম ক্রোম, ৪৪, আমি এটি পেয়েছি: আনকড টাইপ এরিয়ার: ডকুমেন্ট.কোয়ারিসিলিেক্টর সমস্ত ফাংশন নয় (…)
নিক

@ ওমিদহেজাভেহ - যেমনটি আমি বলেছিলাম এটি ইএস 6 কোড। আমি জানি না যে ক্রোম 44 ইএস 6 সমর্থন করে কিনা এবং যদি তা হয় তবে তা কভারেজ এ। এটি প্রায় এক বছরের পুরানো ব্রাউজার এবং স্পষ্টতই আপনাকে একটি কোড ব্রাউজারে চালাতে হবে যা ES6 স্প্রেড সমর্থন করে supports
vsync

বা মৃত্যুদন্ড আগে es5 তা transpile
HelloWorld

8

এই সহজ কৌশল ব্যবহার করুন

<Your array> = [].map.call(<Your dom array>, function(el) {
    return el;
})

আপনি কি দয়া করে ব্যাখ্যা করতে পারেন যে আপনি কেন মনে করেন এর ব্যবহারের চেয়ে সাফল্যের আরও ভাল সুযোগ আছে Array.prototype.slice(বা [].sliceআপনি যেমন রেখেছেন)? একটি নোট হিসাবে, আমি মন্তব্য করতে চাই যে আমি Q তে নথিভুক্ত IE নির্দিষ্ট ত্রুটি IE 8 বা তার চেয়ে কম ক্ষেত্রে ঘটে, যেখানে mapকোনওভাবে প্রয়োগ করা হয় না। আই ই 9 ( "মান মোড") বা উচ্চতর, উভয় sliceএবং mapএকই ভাবে সফল।
22:55

6

যদিও এটি যথাযথ শিম নয়, যেহেতু ডিওএম উপাদানগুলির সাথে কাজ করার কোনও নির্দিষ্টতা নেই, আমি আপনাকে slice()এই পদ্ধতিতে ব্যবহারের অনুমতি দেওয়ার জন্য একটি তৈরি করেছি : https://gist.github.com/brettz9/6093105

আপডেট : আমি যখন এটি ডিএম 4 স্পেসের সম্পাদকের সাথে উত্থাপিত হয়েছিল (তারা জিজ্ঞাসা করেছিল যে তারা হোস্ট অবজেক্টগুলিতে তাদের নিজস্ব বিধিনিষেধ যোগ করতে পারে কিনা (যাতে চশমাটি প্রয়োগকারীদের প্রয়োজন হয় এই অ্যারেগুলিকে অ্যারে পদ্ধতিতে ব্যবহার করার সময় সঠিকভাবে রূপান্তর করতে হবে) ECMAScript নির্দিষ্ট ছাড়াই যা ছিল বাস্তবায়ন-স্বাধীনতার অনুমতি দেওয়া), তিনি উত্তর দিয়েছিলেন যে "হোস্ট অবজেক্টগুলি ইএস 6 / আইডিএল প্রতি কম-বেশি অপ্রচলিত হয়।" আমি http://www.w3.org/TR/WebIDL/#es-array প্রতি দেখছি যে চশমা এই আইডিএলটিকে "প্ল্যাটফর্ম অ্যারে অবজেক্টস" সংজ্ঞায়িত করতে পারে তবে http://www.w3.org/TR/domcore/ না এটি নতুন আইডিএল ব্যবহার করছে বলে মনে হচ্ছে না HTMLCollection(যদিও মনে হচ্ছে এটি এটি করছে কারণ Element.attributesএটি কেবল স্পষ্টভাবে জানিয়েছে যে এটি ডিওএমএসস্ট্রিং এবং ডোমটাইমস্ট্যাম্পের জন্য ওয়েবআইডিএল ব্যবহার করছে)। আমি দেখছি[ArrayClass](যা অ্যারে.প্রোটোটাইপ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত) এর জন্য ব্যবহৃত হয় NodeList(এবং NamedNodeMapএখন কেবলমাত্র এটি ব্যবহার করা হবে এমন একমাত্র আইটেমের পক্ষে অবমুক্ত করা হয়েছে) Element.attributes) যাই হোক না কেন, দেখে মনে হচ্ছে এটি স্ট্যান্ডার্ড হয়ে উঠবে। ES6 এ Array.fromজাতীয় রূপান্তরগুলির জন্য নির্দিষ্ট করে তুলনায় Array.prototype.sliceআরও শব্দার্থিকভাবে পরিষ্কার হতে পারে [].slice()(এবং সংক্ষিপ্ত রূপটি Array.slice()(একটি "অ্যারে জেনেরিক"), যতদূর আমি জানি, স্ট্যান্ডার্ড আচরণে পরিণত হয়নি)।


আমি উল্লেখ করেছি যে চশমাগুলি এই আচরণের প্রয়োজনের দিকে এগিয়ে চলেছে indicate
ব্রেট জামির

5

আজ, 2018 এ, আমরা ECMAScript 2015 (6th ষ্ঠ সংস্করণ) বা ES6 ব্যবহার করতে পারি, তবে সমস্ত ব্রাউজারগুলি এটি বুঝতে পারে না (যেমন প্রাক্তন, IE এটি সব বুঝতে পারে না)। আপনি যদি চান তবে আপনি ES6 নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন: var array = [... NodeList];( স্প্রেড অপারেটর হিসাবে ) বাvar array = Array.from(NodeList);

অন্যান্য যদি (যদি আপনি ES6 ব্যবহার করতে পারবেন না) আপনি সবচেয়ে কম উপায় রূপান্তর করতে ব্যবহার করতে পারেন NodeListএকটি থেকেArray :

var array = [].slice.call(NodeList, 0);

উদাহরণ স্বরূপ:

var nodeList = document.querySelectorAll('input');
//we use "{}.toString.call(Object).slice(8, -1)" to find the class name of object
console.log({}.toString.call(nodeList).slice(8, -1)); //NodeList

var array = [].slice.call(nodeList, 0);
console.log({}.toString.call(array).slice(8, -1)); //Array

var result = array.filter(function(item){return item.value.length > 5});

for(var i in result)
  console.log(result[i].value); //credit, confidence
<input type="text" value="trust"><br><br>
<input type="text" value="credit"><br><br>
<input type="text" value="confidence">

কিন্তু আপনি যদি পুনরুক্তি উপর চান DOMশুধুমাত্র সহজ নোড তালিকা, তাহলে আপনি একটি রূপান্তর করতে প্রয়োজন হবে না NodeListএকটি থেকে Array। এটি NodeListব্যবহার করে আইটেমগুলি লুপ করা সম্ভব :

var nodeList = document.querySelectorAll('input');
// Calling nodeList.item(i) isn't necessary in JavaScript
for(var i = 0; i < nodeList.length; i++)
    console.log(nodeList[i].value); //trust, credit, confidence
<input type="text" value="trust"><br><br>
<input type="text" value="credit"><br><br>
<input type="text" value="confidence">

তালিকার আইটেমগুলি ব্যবহার for...inবা for each...inগণনা করার জন্য প্রলোভিত হবেন না , NodeListকারণ এটির দৈর্ঘ্য এবং আইটেমের বৈশিষ্ট্যগুলিও গণনা করা হবে এবং ত্রুটির কারণ হতে পারে যদি আপনার স্ক্রিপ্টটি ধরে নেয় যে এটি কেবলমাত্র উপাদানগুলির সাথে কাজ করে। এছাড়াও, for..inকোনও নির্দিষ্ট ক্রমে সম্পত্তিগুলি দেখার নিশ্চয়তা নেই। for...ofলুপগুলি নোডলিস্ট অবজেক্টগুলিকে সঠিকভাবে লুপ করবে।

খুব দেখুন:


3
var arr = new Array();
var x= ... get your nodes;

for (i=0;i<x.length;i++)
{
  if (x.item(i).nodeType==1)
  {
    arr.push(x.item(i));
  }
}

এটি কাজ করা উচিত, ব্রাউজার ক্রস করে আপনার সমস্ত "এলিমেন্ট" নোড পান।


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