const form = document.querySelector('.form');
const items = [...form.querySelectorAll('.form__item')];
form.addEventListener('change', function(e) {
const index = items.indexOf(e.target.closest('.form__item'));
form.querySelector('.form__progress-line').style.width = (index + 2) * 100 / items.length + '%';
setTimeout(() => {
items[index]?.classList.remove('form__item--active');
items[index + 1]?.classList.add('form__item--active');
if (index + 1 === items.length) {
form.style.display = 'none';
document.querySelector('.result').classList.add('result--active');
}
}, 1000);
});
form.dispatchEvent(new Event('change'));
$(window).scroll(function() {
const $banner = $('.banner');
const bannerHeight = $banner.outerHeight(true);
const bannerTop = parseInt($banner.css('top'), 10);
const windowTop = $(this).scrollTop();
$banner.toggleClass('hide', $('.fullwidth').get().some(n => {
const $n = $(n);
const nTop = $n.offset().top - bannerTop;
const minTop = nTop - bannerHeight;
const maxTop = nTop + $n.outerHeight(true);
return windowTop > minTop && windowTop < maxTop;
}));
});
const join = val => Array.isArray(val) ? val.map(join).join('') : val;
const join = arr => ''.concat(...arr.flat(Infinity));
const join = arr => arr.reduce((acc, n) => acc + (n instanceof Array ? join(n) : n), '');
function join(arr) {
const result = [];
for (const stack = [ arr ]; stack.length;) {
const n = stack.pop();
if (n?.constructor === Array) {
stack.push(...[...n].reverse());
} else {
result.push(n);
}
}
return result.join``;
}
$('form').on('input', function() {
$('#submit-about').prop('disabled', ![
$('#name-about').val().length !== 0,
$('#phone-about').val().length === 16,
$('#personaldata-about').prop('checked'),
].every(Boolean));
});
.dropdown {
display: none;
}
.dropdown.show {
display: block;
}
const headerSelector = '.tabs__head';
const contentSelector = '.dropdown';
const activeClass = 'show';
// делегирование, назначаем обработчик клика один раз для всех хедеров;
// контент, соответствующий нажатому хедеру, находим через значение атрибута href
document.addEventListener('click', ({ target: t }) => {
const header = t.closest(headerSelector);
if (header) {
document.querySelectorAll(contentSelector).forEach(function(n, i) {
n.classList[n === this ? 'toggle' : 'remove'](activeClass);
}, document.querySelector(header.attributes.href.value));
}
});
// или, назначаем обработчик клика каждому хедеру индивидуально;
// контент, соответствующий нажатому хедеру, определяем по равенству индексов
const headers = document.querySelectorAll(headerSelector);
const contents = document.querySelectorAll(contentSelector);
headers.forEach(n => n.addEventListener('click', onClick));
function onClick() {
const index = Array.prototype.indexOf.call(headers, this);
contents.forEach((n, i) => n.classList[i === index ? 'toggle' : 'remove'](activeClass));
}
$('.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;
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;
}, {}))