Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Получить прямых потомков в NodeList (https://javascript.ru/forum/misc/59285-poluchit-pryamykh-potomkov-v-nodelist.html)

ruslan_mart 04.11.2015 03:51

Получить прямых потомков в NodeList
 
Пытаюсь написать метод, с помощью которого можно будет получить прямых потомков по имени тэга.
Всех потомков найти не проблема, а проблема как раз таки в NodeList - в JavaScript нельзя создавать свой NodeList/HTMLCollection.

Пока вот до чего додумался:

Element.prototype.getChilds = function(tagName) {
	var childs = this.children,
		nodeList = null;
	if(!tagName || tagName == '*') {
		nodeList = childs;
	}
	else {
		var l = childs.length;
		if(l) {
			var i, tempID = 't' + Math.floor(Math.random() * 9E10).toString(32);
			for(i = 0; i < l; i++) {
				if(childs[i].tagName == tagName.toUpperCase()) {
					childs[i].setAttribute(tempID, '');
				}
			}
			nodeList = document.querySelectorAll('[' + tempID + ']');
			if(nodeList) {
				nodeList.each(Element.prototype.removeAttribute.bind(nodeList, tempID));
				/*nodeList.each(function() {
					this.removeAttribute(tempID);
				});*/
			}
		}
	}
}


В принципе, всё работает как нужно. Но может у кого-нибудь есть идеи более элегантного решения задачи? А то мало ли, вдруг что-то упустил.

Для тех, кто не понял: мне нужно получить NodeList/HTMLCollection элементов, а не массив.

_________________

Пока писал пост, придумал такое решение :)
Element.prototype.getChilds = function(tagName) {
	var childs = this.children, nodeList,
		tempID = 't' + Math.floor(Math.random() * 9E10).toString(32);
	this.setAttribute(tempID, '');
	nodeList = this.parentNode.querySelectorAll('[' + tempID + '] > ' + (tagName || '*'));
	this.removeAttribute(tempID);
	return nodeList;
}

nerv_ 04.11.2015 09:31

1. не понимаю, в чем проблема
element.querySelectorAll('> *')

upd: ok, такой вариант не работает)
тогда http://stackoverflow.com/a/21126966/5215084
или как-то так
function getChildrenByTagName(root, tagName = '*') {
    let originRootId = root.id;
    let tempRootId = '___' + Date.now();
    root.id = tempRootId;
    let children = document.querySelectorAll(`#${tempRootId} > ${tagName}`);
    root.id = originRootId;
    return children;
}

2. я бы не стал "патчить" прототипы встроенных объектов :)

рони 04.11.2015 10:02

nerv_,
а # в строке 5 ненужно?

nerv_ 04.11.2015 10:04

рони, уже добавил) Я проснулся недавно :D Это в рамках погрешности)

рони 04.11.2015 10:06

nerv_,
ок! :)

ruslan_mart 04.11.2015 12:59

Цитата:

Сообщение от nerv_
2. я бы не стал "патчить" прототипы встроенных объектов

Почему? Из-за проблем в старых ишаках? Так на них давно пора забить. :D Или вся проблема в том, чтобы в будущих версиях API могут быть использованы точно такие же названия методов, что и свои? :)

Лично я накатал небольшую либу под себя, несколько новых методов в прототипы Element и NodeList встроил, например: prependChild, appendChildAt, wrapElement. Пока всё устраивает, косяков нигде нет. :) Или есть какие-то другие подводные камни?

loljs 06.11.2015 13:23

А for in не подходит чтоли?

ruslan_mart 06.11.2015 13:39

loljs, причём тут for..in?

loljs 06.11.2015 13:41

А, прошу прощения, я че-то не въехал, я подумал про ключи. Ты про потомков в DOM говоришь. Все понял. Вообще, это фейковые объекты, они не патчатся нормально, ЕМНИП.

loljs 06.11.2015 14:13

Только я че то не въезжаю, зачем ты эти все рандомы и прочее там городишь? Почему так нельзя?
Element.prototype.getChilds = function(tagName) {
   return this.querySelectorAll(tagName)
}


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