function sum(data, key = n => n) {
const getVal = key instanceof Function ? key : n => n[key];
let result = 0;
for (const n of data) {
result += getVal(n);
}
return result;
}
const form = document.querySelector('form');
const result = form.querySelector('.result');
form.addEventListener('change', onChange);
form.dispatchEvent(new Event('change'));
function onChange() {
result.textContent = sum(
this.querySelectorAll(':checked'),
n => +n.getAttribute('rel')
);
}
// или
function onChange(e) {
result.innerText = sum(
e.currentTarget.elements,
n => n.attributes.rel.value * n.checked
);
}
const blockSelector = 'селектор блоков';
const buttonSelector = 'селектор кнопок';
const activeClass = 'класс, показывающий блок';
const blocks = document.querySelectorAll(blockSelector);
const buttons = document.querySelectorAll(buttonSelector);
buttons.forEach((n, i) => {
n.addEventListener('click', () => {
blocks[i].classList.toggle(activeClass);
});
});
const onClick = function({ currentTarget: { dataset: { index } } }) {
this[index].classList.toggle(activeClass);
}.bind(document.querySelectorAll(blockSelector));
document.querySelectorAll(buttonSelector).forEach((n, i) => {
n.dataset.index = i;
n.addEventListener('click', onClick);
});
const blocks = document.querySelectorAll(blockSelector);
const buttons = document.querySelectorAll(buttonSelector);
buttons.forEach(n => n.addEventListener('click', onClick));
function onClick() {
const index = Array.prototype.indexOf.call(buttons, this);
blocks[index].classList.toggle(activeClass);
}
const containerSelector = '...';
), то индексы не нужны. Достаточно от нажатой кнопки подняться до общего предка кнопки и блока, и найти внутри блок (а можно даже и не искать, если добавлять класс контейнеру; конечно, стили придётся в этом случае немного изменить, вместо .блок.класс
будет .контейнер.класс .блок
):const toggleBlock = button => button
?.closest(containerSelector)
?.querySelector(blockSelector)
.classList
.toggle(activeClass);
// можно добавить обработчик клика каждой кнопке индивидуально
document.querySelectorAll(buttonSelector).forEach(function(n) {
n.addEventListener('click', this);
}, e => toggleBlock(e.currentTarget));
// или один раз на всю страницу
document.addEventListener('click', e => {
toggleBlock(e.target.closest(buttonSelector));
});
<card-item :title="Неработающий заголовок"/>
Динамически привязывает один или несколько атрибутов или входных параметров компонента к выражению.
Неработающий заголовок
- это выражение? $minPrices = array_values(array_reduce($arr, function($acc, $n) {
$key = $n['code_id'];
if (!isset($acc[$key]) || $acc[$key]['price'] > $n['price']) {
$acc[$key] = $n;
}
return $acc;
}, []));
const getNestedItems = (data, test) =>
data instanceof Object
? Object.values(data).flatMap(n => getNestedItems(n, test))
: test(data) ? [ data ] : [];
const result = getNestedItems(obj, x => /^[A-Z]+$/.test(x)).join('');
function* getNestedItems(data, test) {
if (Object(data) === data) {
for (const k in data) if (Object.hasOwn(data, k)) {
yield* getNestedItems(data[k], test);
}
} else if (test(data)) {
yield data;
}
}
const result = ''.concat(...getNestedItems(obj, x => x?.toUpperCase?.() === x));
<div class="wrapper" v-if="надо рендерить обёртку">
...
<элемент />
...
</div>
<элемент v-else />
все с атрибутом required
const className = 'здесь ваш класс';
const inputs = document.querySelectorAll(`.${className}`);
// или
const inputs = document.getElementsByClassName(className);
const isFilled = [...inputs].every(n => n.value);
// или
const isFilled = !Array.prototype.some.call(inputs, n => !n.value);
// или
let isFilled = true;
for (const n of inputs) {
if (!n.value) {
isFilled = false;
break;
}
}
// или
let isFilled = true;
for (let i = -1; ++i < inputs.length && (isFilled = !!inputs[i].value);) ;
// или
const isFilled = !(function isEmpty(i, n = inputs.item(i)) {
return n && (!n.value || isEmpty(-~i));
})(0);
if (this.frame < 0) { this.frame = this.slides.lenght-1; this.setBackground(this.slides[this.frame]) }
frame
неотрицательный, то вызывать setBackground
уже не надо?undefined
. А после вычитания единицы - NaN
. Элемента с индексом NaN
в массиве нет, так что в setBackground
улетает undefined
- его вы и видите в стилях.if (this.frame > this.slides.length) {
buttonLeft.addEventListener('click', slider.left());
while не совсем удобен
while
заменить на for
, переместить вызов exec
в условие продолжения цикла - получится одна строка вместо трёх, область видимости вне цикла не загажена не нужной там переменной, вроде бы неплохо:for (let m; m = re.exec(str);) {
console.log(m.groups);
}
exec
стоит по другой причине. Проблема в том, что если забыть флаг g
при определении регулярного выражения, то exec
будет при каждом вызове выдавать первое совпадение, т.е., цикл получится бесконечным. А вот с matchAll
такой ерунды не случится, без флага выдаст ошибку:for (const { groups } of str.matchAll(re)) {
console.log(groups);
}
Array.from(
arr.reduce((acc, n) => acc.set(n, -~acc.get(n)), new Map),
n => [ n[0], (n[1] / arr.length * 100).toFixed(2) + '%' ]
)
yAxis: {
plotLines: [
{
color: 'red',
value: 13,
width: 5,
zIndex: 666,
},
],
...
const clone = (data, replacements) =>
data instanceof Object
? data instanceof Array
? data.map(n => clone(replacements?.hasOwnProperty(n) ? replacements[n] : n, replacements))
: Object.fromEntries(Object.entries(data).map(([ k, v ]) => [
k,
clone(replacements?.hasOwnProperty(k) ? replacements[k] : v, replacements)
]))
: data;
const products = arr.map(n => clone(obj.product[0], n));
"[object Object]"
. Всё.toString
(конечно, поступать так имеет смысл только в том случае, если вы можете гарантировать, что строковые представления будут уникальны). $doc = new DOMDocument();
$doc->loadHTML($html);
$a = $doc->getElementsByTagName('a');
$result = array_map([ $doc, 'saveHTML' ], iterator_to_array($a));
$result = preg_split('/(?<=\/a>)(?=<a)/', $html);
// или
preg_match_all('/<a .*?>.*?<\/a>/', $html, $matches);
$result = $matches[0];