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);

observer 14.11.2011 03:30

Цитата:

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

Любите потроллить? Ок.

Вчера вы жестко тупили. И после выделения буквы полужирным и после раскраски в красный...


Цитата:

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

Наполнить прототип массива? Хахаха.

Цитата:

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

Иногда, после указательных местоимений пишут в скобках на того, на кого указывают. Так вот, еще раз специально для одаренных:

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

trikadin 14.11.2011 03:43

Цитата:

Сообщение от observer
Любите потроллить?

Учитывая ваши сообщения в личку (да и не только их), тролль - это вы.

Цитата:

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

Если бы вы написали так сразу, недоразумений бы не возникло. Вы же написали, извините, через задницу, и смысл фразы исказился.

Цитата:

Сообщение от observer
Иногда, после указательных местоимений пишут в скобках на того, на кого указывают.

Хах) Не пытайтесь доказать мне, что я плохо знаю русский язык и поэтому не понимаю вас. У вас даже предложение неправильно построено ("пишут в скобках на того" - это как?:)).

observer 14.11.2011 03:48

Цитата:

Сообщение от trikadin (Сообщение 136349)
:dance:

Точно, это вы зайчик с логотипа.

nikita.mmf 14.11.2011 11:47

Расширение прототипа можно сделать, но это не буде работать в IE6-7(они не поддерживают расширение прототивов для элементов и коллекций), например вот так
(HTMLCollection||NodeList) && ((HTMLCollection||NodeList).prototype.forEach = (HTMLCollection||NodeList).prototype.forEach || Array.prototype.forEach);

Но вообще для работы с коолекциями отлично подходят обычные циклы
var elems = document.getElementsByTagName('div'), 
    i = 0, elem;
while( (elem = elems[i++]) ) {

}

Kolyaj 14.11.2011 12:07

Человек без ника,
[].forEach.call(document.getElementsByTagName(someName), function(el) {
    console.log(el);
});


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