Как сделать короткую функцию для forEach?
Здравствуйте.
1. Я не хочу использовать jQuery, но мне нужна от туда фишка с применением параметров на массив объектов (простите, если неправильно использовала термины). Я имею в виду это $(".block").addClass("red") И если есть несколько объектов с классом block, то применится addClass для всех объектов. В чистом JS я делаю это так:
document.querySelectorAll(".block").forEach((el)=> {
el.classList.add("red");
});
Подскажите, как быть с функцией, которая бы делала forEach? Я просто не совсем могу сообразить, как такое сделать. Вот так не работает (ну и не должно)
function qsf(e) {
return
document.querySelectorAll(e).forEach((el)=> {
el
})
}
2. На данный момент я себе сделала 2 функции
function q(e){return document.querySelector(e)}
function qs(e){return document.querySelectorAll(e)}
И теперь обращаюсь через q и qs соответсвенно. Так на много удобнее и короче получается. Вопрос: насколько это правильное решение? Не замедляю ли я таким образом код? Ведь я заставляю его постоянно вызывать функцию. Может быть это как-то сказывается на ОЗУ? 3. Почему раньше, когда я видела js код, постоянно писали getElementById или getElementsByClassName, а не использовали querySelector, ведь так намного проще? Там же можно обратиться и по ID и по Class. Просто для меня, когда я первый раз столкнулась с кодом, лет 5 назад, это было аргументом для того, чтобы использовать jquery. Там только знак доллара, а здесь пипец какой-то. А теперь оказывается, что есть querySelector. P.S. getElementsByClassName я видела как раз в таком виде:
document.getElementsByClassName("block").forEach((el)=> {
el.classList.add("red");
});
и меня это пугало, так как можно было сделать $(".block").addClass("red"); |
Цитата:
|
рони,
как сделать, чтоб возвращало и работало? я classList имела в виду для примера. На деле я хочу именно иметь возможность что-то делать с массивом. То есть получить способности того же $("element").что-то |
forEach со встроенным списком элементов
nastya97core,
<!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;
}
body{
display: flex;
justify-content: center;
}
.red{
background-color: #FF0000;
}
</style>
</head>
<body>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<script>
function qs(e){return document.querySelectorAll(e)};
function qsf(e){
const fn = callback => (NodeList.prototype.forEach.bind(qs(e))(callback), fn);
return fn};
qsf('div')
(el => el.classList.add("red"))
((el,i) => el.textContent = i)
(({style}) => style.color = '#fff');
</script>
</body>
</html>
|
nastya97core,
Rise библиотека в jQuery стиле |
вариант с контекстом
Rise,
:thanks:
<!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;
}
body{
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>
function qsa(selector, parent) {
return (parent || document).querySelectorAll(selector)
}
function qsf(...e) {
const fn = callback => (NodeList.prototype.forEach.bind(qsa(...e))(callback), fn);
return fn
};
let parent = qsa('.item')[0];
qsf('div', parent)
(el => el.classList.add("red"))
((el, i) => el.append(i))
(({style}) => style.color = '#fff');
</script>
</body>
</html>
|
Цитата:
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 возвращают массив, так что вы можете работать как с обычным массивом!Цитата:
<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>
Цитата:
Твой пример, но перечисление только один раз...
<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>
Цитата:
Цитата:
Цитата:
Цитата:
for(const el of document.querySelectorAll(".block")) {
el.classList.add("red");
}
С кодом, вдохновлённым Command Line API, вы можете написать даже так...
for(const el of $$(".block")) {
el.classList.add("red");
}
Цитата:
$$(".block").forEach(el => {
el.classList.add("red");
});
|
Цитата:
потому что это можно, и ничто не мешает сделать всё за один цикл или десять, была продемонстрирована возможность делать цикл за циклом. |
Цитата:
function qsa(selector, parent) {
return (parent || document).querySelectorAll(selector)
}
function qsf(...e) {
const fn = callback => (NodeList.prototype.forEach.bind(qsa(...e))(callback), fn);
return fn
};
var TIMES = 1000, SELECTOR = "body td";
console.time("Длинное каррирование");
eval("qsf('" + SELECTOR + "')\n" + "(e => e.style.background = '#' + ('000000' + Math.floor(0xffffff * Math.random())).slice(-6))\n".repeat(TIMES) + "\n//# sourceURL=Длинное-каррирование")
console.timeEnd("Длинное каррирование");
console.time("Длинный цикл");
eval("for(const e of document.querySelectorAll('" + SELECTOR + "')) {\n" + "\te.style.background = '#' + ('000000' + Math.floor(0xffffff * Math.random())).slice(-6);\n".repeat(TIMES) + "}\n\n//# sourceURL=Длинный-цикл")
console.timeEnd("Длинный цикл");
console.time("Длинное jQuery");
eval("jQuery('" + SELECTOR + "')\n" + "\t.css('background', '#' + ('000000' + Math.floor(0xffffff * Math.random())).slice(-6))\n".repeat(TIMES) + "\n//# sourceURL=Длинное-jQuery")
console.timeEnd("Длинное jQuery");
2. Стиль кода.
qsf("#a .b")
(e => a)
(e => b)
(e => c)
(e => d)
против
for(const e of $$("#a .b")) {
a;
b;
c;
d;
}
3. Кто опишет этот сложный тип в JSDoc? Visual Studio Code, WebStorm и пр. понимают синтаксис JSDoc, что позволяет использовать автоматическое дополнение, подсказки и ранний анализ кода. |
Malleys,
1 мне сложно понять, при чём тут скорость ... 2 что вам мешает записать все изменения в одном цикле!!! qsf("#a .b")(e => abcd) 3. увы , я не владею современными средствами разработки, туго как то с наукой и учителями. |
| Часовой пояс GMT +3, время: 13:51. |