function navFunction(id) {
for (const n of document.querySelectorAll('.dropdown2-content')) {
n.classList[n.id === id ? 'toggle' : 'remove']('show');
}
}
.dropdown2 .dropdown2-content {
display: none;
}
.dropdown2.show .dropdown2-content {
display: block;
}
const containerSelector = '.dropdown2';
const buttonSelector = `${containerSelector} .dropbtn2`;
const activeClass = 'show';
// делегирование, назначаем обработчик клика один раз для всех кнопок
document.addEventListener('click', e => {
const button = e.target.closest(buttonSelector);
if (button) {
document.querySelectorAll(containerSelector).forEach(function(n) {
n.classList[n === this ? 'toggle' : 'remove'](activeClass);
}, button.closest(containerSelector));
}
});
// или, назначаем обработчик клика каждой кнопке индивидуально
const onClick = function({ currentTarget: t }) {
this.forEach((n, i) => n.classList[n.contains(t) ? 'toggle' : 'remove'](activeClass));
}.bind(document.querySelectorAll(containerSelector));
document.querySelectorAll(buttonSelector).forEach(n => {
n.addEventListener('click', onClick);
});
"true"
и true
. const inputSelector = '#icons_care';
const checkboxSelector = '.check_care';
const checkboxCheckedSelector = `${checkboxSelector}:checked`;
const dataAttr = 'icon';
const separator = ', ';
$(document).on('change', checkboxSelector, () => {
$(inputSelector).val($(checkboxCheckedSelector)
.get()
.map(n => $(n).data(dataAttr))
.join(separator)
);
});
// или
document.addEventListener('change', e => {
if (e.target.matches(checkboxSelector)) {
const input = document.querySelector(inputSelector);
const cb = document.querySelectorAll(checkboxCheckedSelector);
input.value = Array.from(cb, n => n.dataset[dataAttr]).join(separator);
}
});
const buttonSelector = '.button';
const blockSelector = '.div';
const activeClass = 'red';
function toggleBlock(blocks, buttons, button) {
const index = Array.prototype.indexOf.call(buttons, button);
blocks.forEach((n, i) => {
n.classList[i === index ? 'toggle' : 'remove'](activeClass);
});
}
// обработчик клика делегированный, назначается один раз
document.addEventListener('click', e => {
const button = e.target.closest(buttonSelector);
if (button) {
const blocks = document.querySelectorAll(blockSelector);
const buttons = document.querySelectorAll(buttonSelector);
toggleBlock(blocks, buttons, button);
}
});
// или, назначаем обработчик клика каждой кнопке индивидуально
const buttons = document.querySelectorAll(buttonSelector);
const blocks = document.querySelectorAll(blockSelector);
const onClick = e => toggleBlock(blocks, buttons, e.currentTarget);
buttons.forEach(n => n.addEventListener('click', onClick));
<input class="date">
<input class="date">
<input class="date">
const yearButton = year => `
<button
data-year="${year}"
class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all"
>${year}</button>
`;
$('.date').datepicker({
showButtonPanel: true,
}).each(function(i) {
$(this).datepicker(
'option',
'currentText',
`Today ${yearButton(2015 + i * 2)}${yearButton(2015 + i * 2 + 1)}`
);
});
$(document).on('click', '[data-year]', function() {
$.datepicker._curInst.input.datepicker('setDate', `01/01/${$(this).data('year')}`);
});
const nestedToPlain = (obj, path = '') =>
Object.entries(obj).reduce((acc, [ k, v ]) => {
const newPath = `${path}${path ? '.' : ''}${k}`;
return Object.assign(acc, v instanceof Object
? nestedToPlain(v, newPath)
: { [newPath]: v }
);
}, {});
const plain = nestedToPlain(example, 'example');
const nestedToPlain = (obj, keys = []) =>
Object.entries(obj).reduce((acc, [ k, v ]) => (
keys.push(k),
Object.assign(acc, v instanceof Object
? nestedToPlain(v, keys)
: { [keys.join('.')]: v }
),
keys.pop(),
acc
), {});
const plain = nestedToPlain(example, [ 'example' ]);
const nestedToPlain = function(obj, keys = []) {
const result = {};
const [ push, pop ] = this;
for (const stack = [ obj ]; stack.length;) {
const n = stack.pop();
if (n instanceof Object) {
Object.entries(n).reverse().forEach(([ k, v ]) => stack.push(pop, v, k, push));
} else if (n === push) {
keys.push(stack.pop());
} else if (n === pop) {
keys.pop();
} else {
result[keys.join('.')] = n;
}
}
return result;
}.bind([ Symbol(), Symbol() ]);
const plain = nestedToPlain(example, [ 'example' ]);
const newArr = arr
.filter(function(n) {
return !(this[n.country] = this.hasOwnProperty(n.country));
}, {})
.map((n, i) => ({ id: i + 1, country: n.country }));
const newArr = Object.values(arr.reduce((acc, { country }) => {
acc[0][country] = acc[0][country] || { id: ++acc[1], country };
return acc;
}, [ {}, 0 ])[0]);
const newArr = Array.from(arr.reduce((acc, { country: n }) => (
acc.set(n, acc.get(n) || { id: -~acc.size, country: n })
), new Map).values());
const keys = [ 'firstName', 'lastName' ];
const values = document.querySelector('input').value.toLowerCase().match(/\S+/g) || [];
const result = arr.filter(n => keys.some(k => values.some(v => n[k].toLowerCase().includes(v))));
Нетривиальная задача
<svg
data-color-index="-1"
data-color-attr="fill"
...
<span
data-color-index="-1"
data-color-attr="color"
...
$('svg, span').mouseenter(function() {
const colorIndex = (+this.dataset.colorIndex + 1) % colors.length;
$(this).css(this.dataset.colorAttr, colors[colorIndex]);
this.dataset.colorIndex = colorIndex;
}).mouseleave(function() {
$(this).css(this.dataset.colorAttr, '');
});
let index = -1;
$('.demo').mouseenter(function() {
index = (index + 1) % colors.length;
updateColor(this, colors[index]);
}).mouseleave(function() {
updateColor(this, '');
});
function updateColor(el, color) {
$('[data-color-attr]', el).each(function() {
$(this).css(this.dataset.colorAttr, color);
});
}
function sum(...values) {
const s = values.reduce((acc, n) => acc + n, 0);
const f = sum.bind(null, s);
f.valueOf = () => s;
return f;
}
Object.entries(Obj).reduce((acc, [ k, v ]) => ((acc[v] = acc[v] || []).push(k), acc), {})
- .popup.visible {
+ .item.visible .popup {
const container = document.querySelector('.container');
const itemSelector = '.item';
const activeClass = 'visible';
const toggleItem = (item, items) =>
items.forEach(n => n.classList[n === item ? 'toggle' : 'remove'](activeClass));
// делегирование, назначаем обработчик клика один раз для всех item'ов
container.addEventListener('click', function({ target: t }) {
if (t.matches(itemSelector)) {
toggleItem(t, this.querySelectorAll(itemSelector));
}
});
// или, каждому item'у назначаем обработчик клика индивидуально
const items = container.querySelectorAll(itemSelector);
items.forEach(n => n.addEventListener('click', onClick));
function onClick({ target: t }) {
if (this === t) {
toggleItem(t, items);
}
}
const itemSelector = '.accordion_item';
const buttonSelector = `${itemSelector} .title_block`;
const contentSelector = '.info';
const activeClass = 'active_block';
const toggleEffect = 'slideToggle'; // или fadeToggle, или toggle
const onClick = e => $(e.currentTarget)
.closest(itemSelector)
.toggleClass(activeClass)
.find(contentSelector)
[toggleEffect]();
// обработчик клика подключаем к заголовкам
$(buttonSelector).click(onClick);
// или, если предполагается добавление новых секций аккордеона уже после
// подключения обработчика, то лучше будет повесить его на документ,
// дополнительно указав, у каких элементов надо слушать событие;
// в этом случае клики по динамически добавляемым элементам будут
// обрабатываться так же, как и по тем, что существовали изначально
$(document).on('click', buttonSelector, onClick);
function connectInputs(selector) {
const onInput = e => $inputs.val(e.target.value);
const $inputs = $(selector).on('input', onInput);
return () => $inputs.off('input', onInput);
}
connectInputs('#input, #output');
function connectInputs([...inputs]) {
const onInput = e => inputs.forEach(n => n.value = e.target.value);
inputs.forEach(n => n.addEventListener('input', onInput));
return () => inputs.forEach(n => n.removeEventListener('input', onInput));
}
connectInputs(document.querySelectorAll('#input, #output'));
const length = Math.max(...players.map(n => n.holes.length));
for (const { holes } of players) {
holes.push(...Array.from(
{ length: length - holes.length },
() => ({ score: '-' })
));
}
const newPlayers = players.map(n => ({
...n,
holes: Array.from({ length }, (_, i) => n.holes[i] || { score: '-' }),
}));