for (let i = 1; i < arr.length; i++) {
if (arr[i] === arr[i - 1]) {
for (let j = i--; ++j < arr.length; arr[j - 1] = arr[j]) ;
arr.pop();
}
}arr.reduceRight((_, n, i, a) => i && n === a[i - 1] && a.splice(i, 1), null);arr.splice(0, arr.length, ...arr.filter((n, i, a) => !i || a[i - 1] !== n));arr.length -= arr.reduce((acc, n, i, a) => (
a[i - acc] = n,
acc + (i && n === a[i - 1 - acc])
), 0);
function sort(arr, order, key = n => n) {
const positions = new Map(order.map((n, i) => [ n, i ]));
const getPosition = n => positions.get(key(n)) ?? Number.MAX_SAFE_INTEGER;
return arr.sort((a, b) => getPosition(a) - getPosition(b));
}function sorted(arr, order, key = n => n) {
const ordered = new Map(order.map(n => [ n, [] ]));
const unordered = [];
arr.forEach(n => (ordered.get(key(n)) ?? unordered).push(n));
return [].concat(...ordered.values(), unordered);
}a1 = [ '999', '290', '999', '222', '333', '987', '309', '666', '999' ];
a2 = [ '999', '222', '666' ];
sorted(a1, a2) // [ '999', '999', '999', '222', '666', '290', '333', '987', '309' ]
a1 = [ 12, 34, 6, 2, 55, 523, 23, 333, 16, 51 ];
a2 = [ 3, 5, 2 ];
sorted(a1, a2, n => +`${n}`[0]) // [ 34, 333, 55, 523, 51, 2, 23, 12, 6, 16 ]
a1 = [ 666, 'xxx', () => [], true, 1, () => null, false, 'aaa', [0] ];
a2 = [ 'boolean', 'string', 'function' ];
sort(a1, a2, n => typeof n);
a1 // [ true, false, 'xxx', 'aaa', () => [], () => null, 666, 1, [ 0 ] ]
.active {
background: red;
}document.querySelector('table').addEventListener('change', ({ target: t }) => {
t.closest('tr').classList.toggle('active', t.checked);
});
// или
document.querySelectorAll('table tr').forEach(function(n) {
n.addEventListener('change', this);
}, e => e.currentTarget.classList.toggle('active', e.target.checked));tr:has(.form-check-input:checked) {
background: red;
}
const names = Array.from(
document.querySelectorAll('#mainTable input:checked'),
n => n.name
);const names = Array.prototype.reduce.call(
document.getElementById('mainTable').getElementsByTagName('input'),
(acc, n) => (n.checked && acc.push(n.getAttribute('name')), acc),
[]
);
- .box.closed .list {
- display: none;
- }
+ .box .list {
+ display: none;
+ }
+ .box.opened .list {
+ display: block;
+ }const containerSelector = '.section';
const itemSelector = '.box';
const buttonSelector = '.control-label';
const activeClass = 'opened';
// jquery, как вы и хотели
$(itemSelector).on('click', buttonSelector, ({ delegateTarget: t }) => $(t)
.toggleClass(activeClass)
.closest(containerSelector)
.find(itemSelector)
.not(t)
.removeClass(activeClass)
);
// или, к чёрту jquery;
// вешаем обработчик клика на каждый заголовок
const onClick = ({ currentTarget: t }) => t
.closest(containerSelector)
.querySelectorAll(itemSelector)
.forEach(function(n) {
n.classList[n === this ? 'toggle' : 'remove'](activeClass);
}, t.closest(itemSelector));
document
.querySelectorAll(`${containerSelector} ${buttonSelector}`)
.forEach(n => n.addEventListener('click', onClick));
// или, добавляем обработчик клика один раз для всех
document.addEventListener('click', ({ target: t }) => t
.closest(buttonSelector)
?.closest(containerSelector)
?.querySelectorAll(itemSelector)
.forEach(n => n.classList[n.contains(t) ? 'toggle' : 'remove'](activeClass))
);
Object.keys(a).forEach(k => b.hasOwnProperty(k) && (a[k] = b[k]));for (const [ k, v ] of Object.entries(b)) {
if (a.hasOwnProperty(k)) {
a[k] = v;
}
}
function collectValues(target, ...sources) {
const onInput = () => target.value = sources.map(n => n.value).join(', ');
sources.forEach(n => n.addEventListener('input', onInput));
return () => sources.forEach(n => n.removeEventListener('input', onInput));
}
collectValues(...document.querySelectorAll('input'));
Object.values(arr.reduce((acc, { a, b }) => (
(acc[a] ??= { a, items: [] }).items.push(b),
acc
), {}))
// или
Array.from(arr.reduce((acc, { a, b }) => (
acc.set(a, acc.get(a) ?? []).get(a).push(b),
acc
), new Map), ([ a, items ]) => ({ a, items }))
document.addEventListener('click', ((val, e) => {
console.log(val);
}).bind(null, isOpenInputForSearch));
toggle не срабатывает при клике на элемент. Не присваивает классы и не убирает.
Клик происходит по label
const result = [...arr]
.sort((a, b) => a.length - b.length)
.reduce((acc, n) => (
acc.some(m => n.includes(m)) || acc.push(n),
acc
), []);const result = arr.filter((n, i, a) => !a.some((m, j) => i !== j && n.includes(m)));
const className = 'doc';.const wrapFirstWord = el =>
el.innerHTML = el.innerText.replace(/\S+/, '<span>$&</span>');
// или
const wrapFirstWord = el =>
el.innerHTML = el.innerHTML
.split(' ')
.map((n, i) => i ? n : `<span>${n}</span>`)
.join(' ');
// или
function wrapFirstWord(el) {
const i = el.textContent.indexOf(' ');
const span = document.createElement('span');
span.append(el.textContent.slice(0, i));
el.replaceChildren(span, el.textContent.slice(i));
}
// или
function wrapFirstWord({ childNodes: [ text ] }) {
const [ , first, rest ] = text.nodeValue.match(/(\S+)(.*)/);
const span = document.createElement('span');
span.appendChild(new Text(first));
text.nodeValue = rest;
text.parentNode.insertBefore(span, text);
}document.querySelectorAll(`.${className}`).forEach(wrapFirstWord);
// или
for (const n of document.getElementsByClassName(className)) {
wrapFirstWord(n);
}
if(num=>5&&num<=10){=> - никакой это не оператор сравнения.true.
const pick = (obj, keys) => Object.fromEntries(keys.map(k => [ k, obj[k] ]));
const newArr = arr.map(n => pick(n, keys));const pick = (obj, keys) =>
Object.fromEntries(Object.entries(obj).filter(m => keys.includes(m[0])));
// или
const pick = (obj, keys) =>
keys.reduce((acc, n) => (obj.hasOwnProperty(n) && (acc[n] = obj[n]), acc), {});
a, показывать пытаетесь img.document.querySelectorAll('.photos img').forEach(n => {
n.parentNode.style.display = +n.alt === alt ? '' : 'none';
});
function getTimes(start, end, interval) {
const [ s, e ] = [ start, end ].map(n => moment(n, 'HH:mm'));
const result = [];
if (s > e) {
e.add(1, 'day');
}
for (; s <= e; s.add(interval, 'minutes')) {
result.push(s.format('HH:mm'));
}
return result;
}function getTimes(start, end, interval) {
const [ s, e ] = [ start, end ].map(n => new Date(`2000-01-01 ${n}`));
const result = [];
if (s > e) {
e.setDate(e.getDate() + 1);
}
for (; s <= e; s.setMinutes(s.getMinutes() + interval)) {
result.push(s.toTimeString().split(':', 2).join(':'));
// или
result.push(s.toLocaleTimeString('ru', {
hour: '2-digit',
minute: '2-digit',
}));
}
return result;
}const times = getTimes('10:00', '18:00', 30);.
const valueAndClass = [
[ 'yes', 'bg-success' ],
[ 'no', 'bg-warning' ],
];document.querySelector('table').addEventListener('change', e => {
for (const td of e.target.closest('tr').cells) {
for (const [ value, className ] of valueAndClass) {
td.classList.toggle(className, value === e.target.value);
}
}
});bg-primary у ячеек, добавьте его строкам, а обработчик события change пусть будет таким, например:document.querySelector('table').addEventListener('change', ({ target: t }) => {
const tr = t.closest('tr');
valueAndClass.forEach(n => tr.classList.toggle(n[1], n[0] === t.value));
});
const $container = $('.promo__cats');
$container.append(...$container
.children()
.get()
.map(n => [ n, +$('.promo__price', n).text().replace(/\D/g, '') ])
.sort((a, b) => a[1] - b[1])
.map(n => n[0])
);