Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Помогите прикрутить forEach к HTMLCollection и NodeList (https://javascript.ru/forum/misc/23148-pomogite-prikrutit-foreach-k-htmlcollection-i-nodelist.html)

­­­ 13.11.2011 23:43

Помогите прикрутить forEach к HTMLCollection и NodeList
 
Есть задача — заставить работать такой кусок кода:

Код:

var elements = document.getElementsByTagName(someName);
elements.forEach(someFunction);

Достаточно решения в современных браузерах, где поддерживается «родной» forEach для обычных массивов. Кроме того, нужно решение на чистом JavaScript + DOM, без jQuery и других библиотек.

Я нашёл весьма кривое и топорное решение задачи. Надеюсь, что здесь мне подскажут более прямое.

Вот что я сделал:

// Это для IE и Firefox:

if (HTMLCollection.prototype.forEach === undefined) {
  HTMLCollection.prototype.forEach = function(callback, thisObj) {
    Array.prototype.forEach.call(this, callback, thisObj);
  }
}

// Это для Chrome:

if (NodeList.prototype.forEach === undefined) {
  NodeList.prototype.forEach = function(callback, thisObj) {
    Array.prototype.forEach.call(this, callback, thisObj);
  }
}


После этого требуемый кусок кода работает. Однако, для начала, мне не нравится дикое дублирование кода. Хочется свернуть две конструкции в одну, но я путаюсь с тем, как передавать параметры туда-сюда.

Затем, я предполагаю, что моё решение может оказаться в принципе неграмотным и непрофессиональным, а настоящие специалисты решали бы эту задачу как-нибудь совсем по-другому.

Помогите разобраться, пожалуйста.

observer 13.11.2011 23:52

Работайте с прототипом массива (https://developer.mozilla.org/en/Jav.../Array/forEach). Наполните его DOM-нодами и работайте с ним.

Не нужно мучать прототипы DOM-интерфейсов. Не дело это.

­­­ 14.11.2011 00:01

Спасибо за быстрый ответ.

Боюсь, я не очень понимаю, что значит «наполнить прототип массива DOM-нодами». Я не профессиональный программист, и немного теряюсь. Если не сложно, поясните, пожалуйста; лучше с примером кода.

trikadin 14.11.2011 00:30

Цитата:

Сообщение от observer
Наполните его DOM-нодами и работайте с ним.

Причём здесь "DOM-ноды"?

Парень, а что ты с ником сделал? Я его не вижу... Ладно, неважно. Про прототипы и ООП-модель JavaScript в целом можно (и нужно, а то ничего не поймёте) почитать тут.

observer 14.11.2011 01:36

Цитата:

Сообщение от trikadin (Сообщение 136312)
Причём здесь "DOM-ноды"?


In the HTML DOM, each node is an object.

Objects have methods and properties that can be accessed and manipulated by JavaScript.

trikadin 14.11.2011 01:51

observer, не тупите. То, что все кошки - животные, ещё не значит, что все животные - кошки. То, что каждая нода в DOM'е - объект, ещё не означает, что все объекты можно называть DOM-нодами.

И уж тем более, DOM-нодами нельзя назвать методы объекта, записанные к нему в прототип.

P. S. Почему не по-русски, кстати?

observer 14.11.2011 02:27

Цитата:

Сообщение от trikadin (Сообщение 136338)
То, что каждая нода в DOM'е - объект, ещё не означает, что все объекты можно называть DOM-нодами.

А кто назвал все объекты DOM-узлами?

Цитата:

Сообщение от trikadin (Сообщение 136338)
И уж тем более, DOM-нодами нельзя назвать методы объекта, записанные к нему в прототип.

Я такое написал, правда?

Цитата:

Сообщение от trikadin (Сообщение 136338)
P. S. Почему не по-русски, кстати?

Цитата. Перевод тут не к чему. И так все ясно.

Я написал ровно то, что я написал. Собираем узлы (по селектору, как угодно). Push-им в массив. Работаем с массивом через свойство прототипа forEach.

[document.documentElement, document.getElementsByTagName('a')[0]].forEach(addEvilAttrToElement);

Если вы не поняли ни слова, это ваши проблемы.

trikadin 14.11.2011 02:37

Цитата:

Сообщение от observer
Работайте с прототипом массива. Наполните его DOM-нодами и работайте с ним.

Вы написали так (я убрал ссылку). Значение этой фразы: "наполните прототип массива (а не массив, как вы теперь утверждаете) DOM-нодами и работайте с ним (с прототипом, опять же :D)"

Цитата:

Сообщение от observer
Если вы не поняли ни слова, это ваши проблемы.

Скорее, это стало проблемой того парня, которому вы подсказывали. Это ярко подтверждается его следующим сообщением: "я не очень понимаю, что значит «наполнить прототип массива DOM-нодами»"

И кстати, неумение понятно объясняться и строить связный текст - это именно ваша очень большая проблема.

Цитата:

Сообщение от observer
Я написал ровно то, что я написал.

Это иллюзия, простите. Вам так только кажется.

P. S. Если уж цитата, то хоть источник цитирования указывайте))

­­­ 14.11.2011 02:52

Цитата:

Сообщение от observer (Сообщение 136342)
Собираем узлы (по селектору, как угодно). Push-им в массив.

Допустим, у нас есть коллекция, полученная в результате document.getElementsByTagName(element).

Можно ли превратить её в массив, не используя явный цикл со счётчиком? То есть, без всяких первобытных конструкций вроде for(var i = 0; i < коллекция.length; i++)?

Если скатиться к ручному перебору, то исходная задача теряет смысл. Идея была как раз в том, чтобы для перебора элементов использовать именно forEach, а не искусственные итераторы.

trikadin 14.11.2011 02:58

Можно попробовать так. Но не факт, что сработает)
list= document.getElementsByTagName("div");
arr= [];
arr.push.apply(arr, list);


Часовой пояс GMT +3, время: 19:54.