Показать сообщение отдельно
  #7 (permalink)  
Старый 13.05.2020, 13:22
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от nastya97core
И теперь обращаюсь через q и qs соответственно. Так на много удобнее и короче получается.
Вы можете использовать функции, которые есть в Command Line API:

function $(selector, startNode) {
	return (startNode || document).querySelector(selector);
}
function $$(selector, startNode) {
	var nodes = (startNode || document).querySelectorAll(selector);
	var length = nodes.length;
	Object.setPrototypeOf(nodes, Array.prototype);
	nodes.length = length;
	return nodes;
}
function $x(xpath, startNode) {
	var doc = startNode && startNode.ownerDocument || document;
	var result = doc.evaluate(xpath, startNode || doc, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE);
	var node, nodes = [];
	while(node = result.iterateNext()) nodes.push(node);
	return nodes;
}
Такие функции определены в консоли для разработчиков, почему бы их не воссоздать для использования в проекте? Обратите внимание, что $$ и $x возвращают массив, так что вы можете работать как с обычным массивом!

Сообщение от nastya97core
Вопрос: насколько это правильное решение? Не замедляю ли я таким образом код? Ведь я заставляю его постоянно вызывать функцию. Может быть это как-то сказывается на ОЗУ?
Ну если вам удобно работать с NodeList (например при помощи циклов), то OK. А что там должно замедлять код? Посмотрите на определение функции jQuery и ужаснитесь, насколько там замедляют код! Давайте посмотрим...
<script src="https://charm-launch.glitch.me/selectors.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<style>
.container {
	display: flex;
	justify-content: center;
}
.container > div {
	height: 100px;
	width: 100px;
	margin: 5px;
	text-align: center;
	line-height: 100px;
}
.red {
	background-color: #FF0000;
}

</style>

<div class="info"></div>
<script>
	var html = [], c = ["jQuery", "Command Line API"];
	for(var j = 0; j < c.length; j++) {
		html.push('<section id="' + c[j] + '">');
			html.push('<h1>' + c[j] + '</h1>');
			html.push('<div class="container">');
				for(var i = 0; i < 5; i++) {
					html.push('<div></div>');
				}
			html.push('</div>');
		html.push('</section>');
	}
	document.write(html.join(""));
</script>
 
<script>
	
	var t = performance.now();
	/* сначала идёт пример на jQuery */
	$("[id='jQuery'] .container div")
		.addClass("red")
		.text(i => i)
		.css("color", "white")
	/* конец примера на jQuery */
	var dt1 = performance.now() - t;
	
	$("[id='jQuery'] h1").text(
		$("[id='jQuery'] h1").text() + " (" + dt1 + "ms)" 
	);
	
	jQuery.noConflict();
	
	t = performance.now();
	/* далее идёт пример, вдохновлённый Command Line API */
	$$("[id='Command Line API'] .container div").forEach((e, i) => {
		e.classList.add("red");
		e.textContent = i;
		e.style.color = "white";
	});
	/* конец примера */
	var dt2 = performance.now() - t;
	
	$("[id='Command Line API'] h1").textContent += " (" + dt2 + "ms)";
	/* jQuery обычно на полпорядка медленней, однако на некоторых сложных селекторах jQuery замедляется почти на 3 порядка (т. е. jQuery в 800 раз медленней) */
	$(".info").textContent = "jQuery работает в " + (dt1/dt2) + " раз медленней, чем вдохновление от Command Line API";
</script>


Сообщение от рони
qsf('div')
(el => el.classList.add("red"))
((el,i) => el.textContent = i)
(({style}) => style.color = '#fff');
Зачем такие странные конструкции? Почему каждый раз нужно перечислять элементы? Может стоит прочитать про итераторы?

Твой пример, но перечисление только один раз...
<html lang="ru">
<head>
    <style>
    div{
        height: 100px;
        width: 100px;
        margin: 5px;
        text-align: center;
        line-height: 100px;
    }
    body{
         display: flex;
         justify-content: center;
    }
    .red{
        background-color: #FF0000;
    }
    </style>
 </head>
<body>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

<script>	
for(const [i, el] of document.querySelectorAll("div").entries()) {
	el.classList.add("red")
	el.textContent = i
	el.style.color = '#fff'
}
</script>
</body>
</html>


Твой второй пример с использованием кода, вдохновлённого Command Line API...
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
    div {
        height: 100px;
        width: 100px;
        margin: 5px;
        text-align: center;
        line-height: 100px;
    }
    .item {
         display: flex;
         justify-content: center;
    }
    .red {
        background-color: #FF0000;
    }
    </style>
 </head>
<body>
<div class="item">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

<script src="https://charm-launch.glitch.me/selectors.js"></script>
<script>	/* поиск с контекстом, как любит Rise */
$$("div", $(".item")).forEach((el, i) => {
	el.classList.add("red")
	el.append(i)
	el.style.color = '#fff'
});
</script>
</body>
</html>


Сообщение от nastya97core
Почему раньше, когда я видела js код, постоянно писали getElementById или getElementsByClassName, а не использовали querySelector, ведь так намного проще?
Вы и сейчас можете использовать метод getElementById, который возвращает первый попавшийся элемент с данным id. Не использовали метод querySelector, поскольку им вероятно нужна была поддержка в IE6-7, в которых такого метода нет. Просто сейчас особо никто и не делает сайты и для IE6-7 тоже!

Сообщение от nastya97core
Просто для меня, когда я первый раз столкнулась с кодом, лет 5 назад, это было аргументом для того, чтобы использовать jquery. Там только знак доллара, а здесь пипец какой-то. А теперь оказывается, что есть querySelector.
Ну 5 лет назад (в 2015 году) все браузеры уже поддерживали метод querySelector. Даже в 2009 году этот метод уже работал и в Firefox и в IE8 и в Safari (c 2008 года) и в Opera! https://caniuse.com/#feat=queryselector

Сообщение от nastya97core
getElementsByClassName я видела как раз в таком виде:
document.getElementsByClassName("block").forEach(el => {
    el.classList.add("red");
});


и меня это пугало, так как можно было сделать $(".block").addClass("red");
Не забывайте, чтобы сделать так $(".block").addClass("red");, вам нужно было подключить ещё намного больше кода, который должен пугать ещё больше!

Сообщение от nastya97core
Подскажите, как быть с функцией, которая бы делала forEach?
Можно вообще обойтись без функции! Используйте циклы.

for(const el of document.querySelectorAll(".block")) {
    el.classList.add("red");
}

С кодом, вдохновлённым Command Line API, вы можете написать даже так...
for(const el of $$(".block")) {
    el.classList.add("red");
}


Сообщение от nastya97core
На деле я хочу именно иметь возможность что-то делать с массивом
Вы можете использовать Array.from чтобы получить массив с элементами из NodeList... или же использовать три вспомогательных функции для работы с CSS- и XPath-селекторами — $ для поиска одного элемента по CSS-селектору, $$ — для поиска всех элементов (возвращает массив элементов) и $x — для поиска элементов по XPath-селектору (возвращает массив элементов). Код $, $$ и $x смотрите выше!
$$(".block").forEach(el => {
    el.classList.add("red");
});
Ответить с цитированием