$('.price_tabs-content button').click(function() {
const $this = $(this);
const on = $this.siblings('p').toggleClass('on').hasClass('on');
$this.text(on ? 'Закрыть' : $this.data('text'));
}).each((i, n) => $(n).data('text', $(n).text()));
$('.price_tabs-content button').click(function() {
$(this).hide().next().show().end().prev().addClass('on');
}).after('<button>Закрыть</button>').next().hide().click(function() {
$(this).hide().prev().show().prev().removeClass('on');
});
const elements = document.querySelector('#list').children;
// или
const elements = document.querySelectorAll('#list li');
const getVal = el => +el.textContent.split(' - ').pop();
// или
const getVal = el => parseInt(el.innerText.replace(/.*\D/, ''));
// или
const getVal = el => el.innerHTML.match(/\d+$/) | 0;
const sum = Array.prototype.reduce.call(
elements,
(acc, n) => acc + getVal(n),
0
);
// или
let sum = 0;
for (const n of elements) {
sum += getVal(n);
}
// или
const sum = (function sum(i) {
return elements[i] ? getVal(elements[i]) + sum(i + 1) : 0;
})(0);
// или
const sum = eval(Array.from(elements, getVal).join('+')) ?? 0;
const digitsOnly = str => str.replace(/\D/g, '');
// или
const digitsOnly = str => (str.match(/\d/g) ?? []).join('');
// или
const digitsOnly = str => ''.concat(...str.matchAll(/\d/g));
// или
const digitsOnly = str => str.split(/\D/).join``;
// или
const digitsOnly = str =>
Array.prototype.reduce.call(
str,
(acc, n) => acc + ('0123456789'.includes(n) ? n : ''),
''
);
document.querySelectorAll('span').forEach(n => {
n.innerText = digitsOnly(n.innerText);
});
// или
for (const n of document.getElementsByTagName('span')) {
n.textContent = digitsOnly(n.textContent);
}
RegExp
в цепочке прототипов: x instanceof RegExp
.RegExp
конструктором значения: x?.constructor === RegExp
.const type = x => x == null ? x : x.constructor;
type() === undefined // true
type(null) === null // true
type(/./) === RegExp // true
type(666) === Number // true
type(type) === Function // true
const typename = x => x?.constructor.name ?? `${x}`;
typename() // 'undefined'
typename(null) // 'null'
typename(false) // 'Boolean'
typename(187) // 'Number'
typename('hello, world!!') // 'String'
typename(/./) // 'RegExp'
typename({}) // 'Object'
typename([]) // 'Array'
typename(document.body) // 'HTMLBodyElement'
typename(document.getElementsByClassName('xxx')) // 'HTMLCollection'
typename(new class XXX {}) // 'XXX'
typename(typename) // 'Function'
const newArr = arr.reduce((acc, n, i) => (acc.push(n + (acc[i - 1] ?? 0)), acc), []);
// или
const newArr = arr.reduce((acc, n) => (acc[0].push(acc[1] += n), acc), [ [], 0 ])[0];
// или
const newArr = arr.map((n, i, a) => eval(a.slice(0, i + 1).join('+')));
// или
const newArr = arr.map((n, i, a) => a.reduce((acc, m, j) => acc + m * (j <= i), 0));
arr.forEach((n, i, a) => a[i] += a[i - 1] ?? 0);
('0' + date.getMonth()).slice(-2)
// или
`${date.getMonth()}`.padStart(2, 0)
date.toLocaleDateString('ru-RU').split('.').reverse().join('.')
// или
date.toLocaleDateString('ru-RU').replace(/(\d+)(\.\d+\.)(\d+)/, '$3$2$1')
return X; // тут НУЖНО ...
return new Promise(resolve => {
const img = new Image();
img.onload = () => resolve(true);
img.onerror = () => resolve(false);
img.src = 'тут ссылка на изображение';
});
document.querySelector('.menu').addEventListener('click', ({ target: t }) => {
if (t.tagName === 'A') {
const submenu = [...t.parentNode.children].find(n => n.classList.contains('sub-menu'));
if (submenu) {
submenu.classList.toggle('red');
}
}
});
for (const n of document.querySelectorAll('.menu a')) {
n.addEventListener('click', onClick);
}
function onClick() {
this.nextElementSibling?.classList.toggle('red');
}
// или
document.querySelectorAll('.sub-menu').forEach(function(n) {
n.previousElementSibling.addEventListener('click', this);
}, e => e.target.nextElementSibling.classList.toggle('red'));
Object.values(arr.reduce((acc, [ id, group, ...values ]) => {
const g = (acc[id] = acc[id] ?? { id, groups: {} }).groups;
(g[group] = g[group] ?? []).push(values);
return acc;
}, {}))
const delay = timeout => new Promise(r => setTimeout(r, timeout));
async function asyncDelayedForEach(arr, callback, timeout) {
for (let i = 0; i < arr.length; i++) {
await callback.call(arr, arr[i], i, arr);
await delay(timeout);
}
}
// или
const asyncDelayedForEach = (arr, callback, timeout) =>
arr.reduce((acc, n, i, a) => acc
.then(() => callback.call(a, n, i, a))
.then(() => delay(timeout))
, Promise.resolve());
Object.values(arr.reduce((acc, [ user, ...data ]) => {
(acc[user] = acc[user] ?? { user, data: [] }).data.push(data);
return acc;
}, {}))
document.querySelector('.todo-app__list').addEventListener('click', e => {
const li = e.target.closest('.todo-app__list-item');
if (li) {
console.log(li.dataset.id);
}
});
const result = arr1.filter(function(n) {
return this.some(m => m.every(([ k, v ]) => v === n[k]));
}, arr2.map(Object.entries));
undefined
, вместо которого с помощью nullish coalescing подставляем просто цену. А чтобы не копипастить извлечение цены, вынесем его в отдельную функцию, которую, как и сам сортируемый массив, можно сделать параметром функции сортировки.const sorted = (arr, key) => arr
.map(n => [ n, key(n) ])
.sort((a, b) => a[1] - b[1])
.map(n => n[0]);
const sortedArr = sorted(arr, n => -(n.price.new ?? n.price).replace(/\D/g, ''));
const uniqueObj = (obj, key = val => val) =>
Object.fromEntries(Object
.entries(obj)
.filter(function(n) {
const k = key(n[1], n[0]);
return !this.has(k) && this.add(k);
}, new Set)
);