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: '-' }),
}));
$('.select-list').change(function() {
const selected = $(':checked', this)
.parent()
.get()
.map(n => $(n).text().trim())
.join(', ');
$('.selected-name--filter').text(selected || 'Любой');
}).change();
const select = document.querySelector('.select-list');
select.addEventListener('change', function() {
const selected = Array
.from(this.querySelectorAll(':checked'), n => n.parentNode.textContent.trim())
.join(', ');
document.querySelector('.selected-name--filter').textContent = selected || 'Любой';
});
select.dispatchEvent(new Event('change'));
$('a').attr('title', function() {
return $(this).text();
});
document.querySelectorAll('a').forEach(n => n.title = n.innerText);
for (const n of document.getElementsByTagName('a')) {
n.setAttribute('title', n.textContent);
}
$('select').change(function() {
$('button').prop('disabled', $(this).val() === '0');
});
document.querySelector('select').addEventListener('change', function() {
document.querySelector('button').disabled = this.value === '0';
});
function getTree(data) {
let root = data.find(n => n.id === 0);
root = { title: root.name.slice(1,-1), id: root.id };
data.filter(n => n.id !== 0).forEach(item => {
const node = item.name.slice(1, -1).split('/').reduce((parent, title) => {
if (!parent.children) {
Object.assign(parent, { children: [], isDirectory: true });
}
let child = parent.children.find(m => m.title === title);
if (!child) {
child = { title };
parent.children.push(child);
}
return child;
}, root);
Object.assign(node, { id: item.id, isDirectory: !!node.isDirectory });
});
return root;
}
const input = document.querySelector('input');
const button = document.querySelector('button');
const num = 6;
input.addEventListener('input', e => {
button.disabled = e.target.value % num;
});
button.addEventListener('click', () => {
if (input.value % num) {
alert('такого нам не надо, пробуй ещё');
}
});
input.addEventListener('change', ({ target: t }) => {
t.value = Math.max(0, (t.value / num | 0) * num);
});
<button data-step="-1">-</button>
<button data-step="+1">+</button>
document.querySelectorAll('[data-step]').forEach(function(n) {
n.addEventListener('click', this);
}, e => input.value = Math.max(0, +input.value + num * e.target.dataset.step));
const data = $('.price')
.filter((i, n) => +n.value)
.closest('tr')
.find('input[type="hidden"]')
.get()
.map(n => n.value);
const data = Array
.from(document.querySelectorAll('.price'))
.filter(n => +n.value)
.map(n => n.closest('tr').querySelector('input[type="hidden"]').value);
const data = Array.prototype.reduce.call(
document.getElementsByClassName('price'),
(acc, { value: v, parentNode: { parentNode: tr } }) => (
+v && acc.push(tr.cells[0].children[0].value),
acc
),
[]
);
когда оба поля заполнены нулями, необходимо выводить всю таблицу
(!min && !max)
. function setNestedValue(root, ...args) {
const val = args.pop();
const key = (args = args.join('.').split('.')).pop();
args.reduce((p, c) => p[c] = p[c] || {}, root)[key] = val;
}
const obj = {};
setNestedValue(obj, 'xxx', 'yyy', 'zzz', 69);
setNestedValue(obj, 'xxx.a.b.c', 187);
setNestedValue(obj, '_', 666);
Не могу понять как правильно написать цикл перебора.
$('.hello').attr('data-class', function() {
return [...this.classList].filter(n => n !== 'hello');
});
document.querySelectorAll('.hello').forEach(n => {
n.dataset.class = n.className.replace(/(^| )hello( | $)/, ' ').trim();
});
$('.hello').attr('data-class', function() {
return this.classList[1];
});
document.querySelectorAll('.hello').forEach(n => {
n.dataset.class = n.className.split(' ').pop();
});
Array.prototype.push.apply(
arr,
newArr.filter(n => !arr.some(m => m.trade_id === n.trade_id))
);
const pushDiff = (target, source, key = n => n) =>
target.push(...source.filter(function(n) {
return !this.has(key(n));
}, new Set(target.map(key))));
pushDiff(arr, newArr, n => n.trade_id);