JavaScript: concat для getElementsByTagName

Иногда гибкость JavaScript немного обманывает. Например, все знают, что getEle­ments­By­Tag­Name возвращает вроде бы массив. И если нам нужно получить все input и textarea, то мы посмотрим в справке, что есть фунция con­cat и — склеим!

Увы, нас ждёт разочарование. То, что приходит — это набор, но не совсем массив. Его надо преобразовывать в Array и уже потом склеивать.

Как склеивать? Обычно рекомендуют Array.prototype.slice.call(document.getElementsByTagName(‘input’), 0) или немыслимое [].slice.call(document.getElementsByTagName(‘input’), 0). Это работает во всех браузерах, кроме… IE. IE считает, что COM-объект HTML­Col­lec­tion вовсе не обзательно будет массивом. И бросает ошибку “JScript object expect­ed.”.

Поэтому мы расширим функцию из предыдущего примера ещё одной полезной тулзой.

function toArray(obj) {
    var array = [];
    for (var i = 0; obj.length && i < obj.length; i++)
      array[i] = obj[i];
    return array;
  }

func­tion setRead­On­ly(){
var item = document.getElementsByTagName(‘input’);
var el, els = toArray(document.getElementsByTagName(‘input’)).concat(toArray(document.getElementsByTagName(‘textarea’)));
for(el in els)
if(els[el].readOnly && typeof(els[el].className) != “unde­fined”)
els[el].className += ’ read­on­ly’;
}