简体   繁体   中英

“push” is not a function [on elements returned by getElementsByTagName]

I have a bit of Javascript where I'm POSTing my form with an XMLHttpRequest, which otherwise works fine, but when I try to add the SELECT values to the array of INPUT values, it seems Javascript has lost its mind (or I have).

This function just builds the "name1=value1&name2=value2" string and passes it along.

The code:

function sendTheForm() {
  var postData = '';
  var inputArr = document.getElementsByTagName('input');
  if (inputArr.hasOwnProperty(length)) alert("ARRAY!!");
  var selects = document.getElementsByTagName('select');
  var tmpObj = new Object();

  for (var i = 0; i < selects.length; i++) {
    tmpObj.name  = selects[i].name;
    tmpObj.value = selects[i].value;
    inputArr.push(tmpObj);
    }

  for (var i = 0; i < inputArr.length; i++) {
    if (inputArr[i].value) {
      if (postData.length) postData += '&';
      postData += inputArr[i].name;
      postData += '=';
      postData += escape(inputArr[i].value);
      }
    }

  makeHttpReq(postData)
  }

The error I get in FireFox is: " inputArr.push is not a function " It does say it's an Array.

Now, besides the fact that it's a method (not a function), it seems something is going badly wrong here, it's right under my nose and I can't see it. Help?

Earlier, I tried doing:

  len = inputArr.length;
  inputArr[len].name = ...

and also got an error that inputArr[31] was undefined. This is probably obvious, but I'm not seeing it. Help?

Having a .length property does not mean that it is an array. getElementsByTagName() returns a DOM 2 NodeList , not an Array .

As Phrogz already said, checking for a length property is NOT a way of checking for an array.

There's only one way to do that, so it works in ALL cases.

And that is using Object.prototype.toString.call(object).slice(8, -1) .

Which gives you the Class value.

  Value               Class      Type
  -------------------------------------
  "foo"               String     string
  new String("foo")   String     object
  1.2                 Number     number
  new Number(1.2)     Number     object
  true                Boolean    boolean
  new Boolean(true)   Boolean    object
  new Date()          Date       object
  new Error()         Error      object
  [1,2,3]             Array      object
  new Array(1, 2, 3)  Array      object
  new Function("")    Function   function
  /abc/g              RegExp     object (function in Nitro/V8)
  new RegExp("meow")  RegExp     object (function in Nitro/V8)
  {}                  Object     object
  new Object()        Object     object

The reason why this isn't working is because the inputArr variable is actually a node list, not a real array .

If you do want it to be an array, you'd loop through it and add all the nodes in it to a real array or you can do this:

var node_array = Array.prototype.slice.call(node_list); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM