2013-02-02 53 views
9

में दो ऑब्जेक्ट (नोडलिस्ट) सरणी विलय करना मैं ऑब्जेक्ट्स के दो एरे मर्ज करने का प्रयास कर रहा हूं ताकि मैं एक फॉर्म को प्रमाणित कर सकूं। सामान्य परिस्थिति विधि इस परिस्थिति में काम नहीं करती है। Concat सामान्य संख्यात्मक और स्ट्रिंग सरणी के साथ काम करता है लेकिन ऑब्जेक्ट सरणी के साथ नहीं है। रेखा var allTags = allInputs.concat(allSelects); काम नहीं करती है।जावास्क्रिप्ट

var allInputs = document.getElementsByTagName("input"); 
alert("Inputs: " + allInputs.length); 

var allSelects = document.getElementsByTagName("select"); 
alert("Selects: " + allSelects.length); 

var allTags = allInputs.concat(allSelects); 
alert("allTags: " + allTags.length); 
+1

इस सरणी वस्तु की तरह अपने सरणी (NodeList) – salexch

+0

यह है, वास्तव में, एक NodeList, और इसलिए concat विधि नहीं है नहीं है। सहायता के लिए – THEtheChad

उत्तर

19

Concat साधारण संख्यात्मक और स्ट्रिंग सरणियों के साथ काम करता है लेकिन वस्तु सरणियों के साथ ऐसा नहीं करता।

वास्तव में, यह होता है, लेकिन NodeList उदाहरणों एक concat विधि की जरूरत नहीं है, और Array#concat की पहचान है कि आप (क्योंकि वे नहीं सरणियों रहे हैं) उन समतल करना चाहते का एक साधन नहीं है।

लेकिन यह अभी भी करने के लिए काफी आसान है (हालांकि, नीचे चेतावनी देखें)। इस लाइन को बदलें:

var allTags = allInputs.concat(allSelects); 

var allTags = []; 
allTags.push.apply(allTags, allInputs); 
allTags.push.apply(allTags, allSelects); 

Live Example लिए | Source

यह एक चाल का एक सा का उपयोग करके काम करता है: Array#push तत्वों के परिवर्तनशील सरणी में जोड़ने के लिए स्वीकार करता है, और Function#applythis के लिए दिए गए मान का उपयोग फ़ंक्शन को कॉल (हमारे मामले में, allTags) और किसी भी array- ऑब्जेक्ट की तरह तर्कों को पास करने के लिए। चूंकि NodeList उदाहरण सरणी की तरह हैं, push खुशी से सरणी पर सूची के सभी तत्वों को धक्का देता है।

Function#apply (वास्तव में एक श्रृंखला होना चाहिए दूसरा तर्क की जरूरत नहीं) के इस व्यवहार बहुत स्पष्ट रूप से विनिर्देश में परिभाषित है, और आधुनिक ब्राउज़रों में अच्छी तरह से समर्थित है।

दुख की बात है, IE6 और 7 से ऊपर का समर्थन नहीं करते हैं, लेकिन फिर, हम उन्हें नहीं समर्थन किया जाना चाहिए, या तो (मैं इसे विशेष रूप से उपयोग कर रहा है मेजबान वस्तुओं   — NodeLists   — Function#apply के दूसरे तर्क के लिए लगता है) । :-) IE8, या तो, जो अधिक समस्याग्रस्त नहीं है। आईई 9 इसके साथ खुश है।

आप IE8 समर्थन करते हैं और इससे पहले, उदासी की जरूरत है, मुझे लगता है कि आप एक उबाऊ पुराने पाश के साथ फंस रहे हैं:

var allInputs = document.getElementsByTagName('input'); 
var allSelects = document.getElementsByTagName('select'); 
var allTags = []; 

appendAll(allTags, allInputs); 
appendAll(allTags, allSelects); 

function appendAll(dest, src) { 
    var n; 

    for (n = 0; n < src.length; ++n) { 
    dest.push(src[n]); 
    } 

    return dest; 
} 

Live Example | Source

IE8 और पहले (और अन्य) पर काम करता है।

+0

ग्रेट धन्यवाद। मैं शुरुआत कर रहा हूँ। – user2035797

+0

@ user2035797: कोई चिंता नहीं, मैंने अब भी एक उदाहरण जोड़ा है जो आईई 8 और इससे पहले काम करता है। –

+0

+1 वाह, ब्राउज़र समर्थन पर सभी जानकारी के लिए धन्यवाद! – Christophe

0

underscore.js में बिल्कुल देखा गया? आप

var allSelectsAndInputs = _.union(_.values(document.getElementsByTagName("input")),_.values(document.getElementsByTagName("select"))); 

कर सकता है अधिक जानकारी के लिए देखें: http://underscorejs.org/#extend

समारोह वस्तुओं के लिए है, लेकिन इस सेटिंग में काम करता है।

+0

असल में, मैं इसके साथ खेल रहा हूं ... यह थोड़ा सा लगता है। समर्थन करना। –

+2

एक बार की आवश्यकता के लिए ऐसी लाइब्रेरी का उपयोग करने का सुझाव न दें ... – MaxArt

+0

यदि आप इसे पसंद करते हैं तो मैं अंडरस्कोर धन्यवाद – user2035797

2

document.get[something] रिटर्न एक NodeList, जो बहुत ही एक Array के समान लगता है, लेकिन है कई विशिष्ट सुविधाओं, जिनमें से दो हैं:

  • यह concat विधि शामिल नहीं है
  • आइटमों की सूची है लाइव। इसका मतलब है कि वे वास्तविक समय में दस्तावेज़ परिवर्तन के रूप में बदल जाते हैं।

    var allInputs = document.getElementsByTagName("input") 
        , allSelects = document.getElementsByTagName("select") 
    ;//nodeLists 
    
    var inputList = makeArray(allInputs) 
        , selectList = makeArray(allSelects) 
    ;//nodeArrays 
    
    var combined = inputList.concat(selectList); 
    
    function makeArray(list){ 
        return Array.prototype.slice.call(list); 
    } 
    

    आप किसी भी खो देंगे और सभी के व्यवहार:

आप वास्तविक विन्यास में, अपने NodeLists मोड़ के साथ कोई परेशानी नहीं है, तो आप प्रभाव आप इच्छा को प्राप्त करने के लिए निम्न कार्य कर सकता है मूल नोडलिस्ट, जिसमें डीओएम में परिवर्तन को दर्शाने के लिए वास्तविक समय में अपडेट करने की क्षमता शामिल है, लेकिन मेरा अनुमान है, यह वास्तव में एक मुद्दा नहीं है।

+0

सावधान रहें कि, मेरे उत्तर के पहले भाग में दिए गए समान समाधान की तरह, यह IE8 या इससे पहले में काम नहीं करेगा। (इसे यहां आज़माएं: http://jsbin.com/iledok/1) * श्वास * कम से कम IE9 सभ्य है। तो आईई 8 और इससे पहले, किसी को एक उबाऊ पुरानी पाश की जरूरत है। –

1

क्या आप साथ काम कर रहे HTMLCollection रों हैं, और वे लाइव संग्रह (यानी, जब आप डोम के लिए एक नोड जोड़ने के लिए, यह स्वचालित रूप से संग्रह करने के लिए जोड़ दिया जाता है कर रहे हैं।

और उदासी, ऐसा नहीं 'टी एक कारण के लिए एक concat विधि है ... तुम क्या करने की जरूरत है यह एक सरणी में बदलने के लिए, अपने लाइव व्यवहार को खोने है:।

var allInputsArray = [].slice.call(allInputs), 
    allSelectsArray = [].slice.call(allSelects), 
    allFields = allInputsArray.concat(allSelectsArray); 
0

मैं क्रम में डोम वस्तुओं को इकट्ठा करने के लिए एक सरल रास्ता मिल गया वे एक पेज या फॉर्म पर दिखाई देते हैं। सबसे पहले, एक डमी क्लास बनाएं ऑब्जेक्ट पर शैली 'reqd' फिर निम्न का उपयोग करें जो पृष्ठ पर दिखाई देने वाले क्रम में एक सूची बनाता है। बस उस वर्ग को जोड़ें जिसे आप एकत्र करना चाहते हैं।

var allTags = document.querySelectorAll("input.reqd, select.reqd"); 
संबंधित मुद्दे