const index = вам виднее, что тут должно быть;
const className = 'header';
const selector = `.${className}`;
const key = 'id';
const attr = `data-${key}`;
const parentSelector = 'table tbody';
):const $elements = $(parentSelector).children();
const $el = $elements.eq(Math.min(index, $elements.length - 1));
const val = ($el.is(selector) ? $el : $el.prev(selector)).attr(attr) ?? null;
// или
const elements = document.querySelector(parentSelector).children;
let val = null;
for (let i = Math.min(index, ~-elements.length); i >= 0; i--) {
if (elements[i].matches(selector)) {
val = elements[i].getAttribute(attr);
break;
}
}
const elementsSelector = 'table tr';
) разные (конкретно в вашем случае это могла бы быть таблица с несколькими tbody
):const val = $(elementsSelector)
.slice(0, index + 1)
.filter(selector)
.last()
.data(key) ?? null;
// или (UPD. На момент публикации вопроса метод findLast отсутствовал,
// вместо него использовалась связка из reverse-find)
const { [key]: val = null } = Array
.from(document.querySelectorAll(elementsSelector))
.slice(0, -~index)
.findLast(n => n.classList.contains(className))
?.dataset ?? {};
Uncaught TypeError: number[i].parents is not a function
number[i]
должно было быть $(number[i])
или number.eq(i)
.$('.person-wr a.desc')
.filter((i, n) => !$(n).text().trim())
.closest('.add-info')
.hide();
document.querySelectorAll('.person-wr a.desc').forEach(n => {
n.closest('.add-info').hidden = !n.text.trim();
});
const itemSelector = '.preliminary-item';
const keys = [ 'name', 'quantity', 'proximity' ];
const sourceSelector = key => `.request-${key}`;
const targetSelector = key => `.result-${key}`;
$(document).on('click', itemSelector, function() {
$.each(keys, (i, n) => {
$(targetSelector(n)).append(`<p>${$(sourceSelector(n), this).text()}</p>`);
});
});
// или
document.addEventListener('click', function({ target: t }) {
if (t = t.closest(itemSelector)) {
keys.forEach((n, i) => this[i].insertAdjacentHTML(
'beforeend',
`<p>${t.querySelector(sourceSelector(n)).textContent}</p>`
));
}
}.bind(keys.map(n => document.querySelector(targetSelector(n)))));
function getGridSize() {
const w = window.innerWidth;
return [ 500, 700, 1225, Infinity ].findIndex(n => n > w) + 1;
}
function getGridSize() {
const w = window.innerWidth;
return [
{ size: 1, maxWidth: 500 },
{ size: 2, maxWidth: 700 },
{ size: 3, maxWidth: 1225 },
{ size: 4, maxWidth: Infinity },
].find(n => n.maxWidth > w).size;
}
const isEqual = (a, b) =>
a.length === b.length && a.every((n, i) => Object.is(n, b[i]));
const includes = (arrs, search) =>
arrs.some(n => isEqual(n, search));
console.log(includes(array, [ 21, 81 ]));
. el.dispatchEvent(new Event('click'));
// или, если обработчик клика висит не на самом svg, а выше
el.dispatchEvent(new Event('click', { bubbles: true }));
const colors = [
{ color: '...', image: '...' },
{ color: '...', image: '...' },
...
];
background-color
на background-image
:const colorsItems = colors
.map(n => `
<button
style="background-image: url(${n.image})"
class="palette-button"
data-color="${n.color}"
></button>`)
.join('');
.palette-button
- приводите в порядок background:background-position: center;
background-size: contain;
background-repeat: no-repeat;
const markerData = [
{ coord: [ ... ], content: '...' },
{ coord: [ ... ], content: '...' },
...
];
markerData.forEach(function(n) {
const marker = new google.maps.Marker({
position: new google.maps.LatLng(...n.coord),
map,
});
marker.addListener('click', function() {
infowindow.setContent(n.content);
infowindow.open(map, marker);
});
});
name="delivery"
, data-post
- пусть оба будут или delivery, или post). Сделайте пустыми строками значения option'ов, которые соответствуют всем вариантам.$('.result-btn').on('click', function() {
const values = $('select')
.get()
.filter(n => n.value)
.map(n => [ n.name, n.value.toLowerCase() ]);
$('.delivery-table-item')
.show()
.filter((i, { dataset: d }) => values.some(([ k, v ]) => d[k].toLowerCase() !== v))
.hide();
});
создаёт новый массив со всеми значениями, для которых функцияcallback
вернула значение, которое может быть приведено кtrue
true
, если элемент массива является числом, то есть, в результирующий массив попадают только числа, и неважно, каковы их значения. Во втором случае вы возвращаете сам элемент, если он является числом, а нули, они да - имеют своим булевым эквивалентом false
, поэтому и отбрасываются. const icons = {
one: [ 'url иконки раскрытия одного элемента', 'и закрытия' ],
all: [ 'url иконки раскрытия всех', 'что здесь должно быть, думаю догадаетесь' ],
};
const getState = el => $(el)
.closest('.team__info-worklog')
.find('.worklog-table')
.get()
.map(n => $(n).is(':visible'));
const setState = (el, state) => $(el)
.closest('.team__info-worklog')
.find('.worklog-table').each((i, n) => $(n)[state[i] ? 'slideDown' : 'slideUp']()).end()
.find('.worklog-expend-all img').attr('src', icons.all[+state.some(Boolean)]).end()
.find('.worklog-list__expend img').attr('src', i => icons.one[+state[i]]);
const createUpdater = f => e => setState(e.target, f(getState(e.target), e));
$('.worklog-expend-all').on('click', createUpdater(state => {
return Array(state.length).fill(!state.some(Boolean));
}));
$('.team__info-worklog').on('click', '.worklog-list__expend', createUpdater((state, e) => {
const index = $(e.target).closest('.worklog-list__row').index();
return state.map((n, i) => i === index ? !n : n);
}));
const blockSelector = '.block';
const buttonSelector = `${blockSelector} button`;
const el = document.querySelector(`${blockSelector} span`);
document.querySelectorAll(buttonSelector).forEach(function(n) {
n.addEventListener('click', this);
}, ({ currentTarget: t }) => {
while (!(t = t.parentNode).matches(blockSelector)) ;
t.appendChild(el); // или t.insertBefore(el, null)
});
document.addEventListener('click', e => e
.target
.closest(buttonSelector)
?.closest(blockSelector)
.append(el) // или .insertAdjacentElement('beforeend', el)
);
const initialValues = [ 100, 100000 ];
const setValues = values => $inputs.val(i => values[i]);
const $slider = $('#slider-range').slider({
range: true,
min: initialValues[0],
max: initialValues[1],
step: 20,
values: initialValues,
slide: (e, ui) => setValues(ui.values),
});
const $inputs = $('#amount_before, #amount_after')
.on('input', () => $slider.slider('values', $inputs.get().map(n => n.value)));
setValues(initialValues);
строка.replace(регулярка, '')
// или
строка.split(регулярка).join('')
вот так я ищу часть текста /ПКБ №\d+/
<...> Нужно найти например слова "новое имя" тут "ПКБ №33 Новое имя"
str.replace(/ПКБ №\d+/, '').trim()
// или
str.split(/ПКБ №\d+\s*/).join``
// или
str.match(/(?<=ПКБ №\d+ ).+/)[0]
// или
/(\S+\s+){2}(.+)/.exec(str).pop()
// или
str.split(' ').slice(2).join(' ')
const select = document.querySelector('[name="id_car_mark"]');
blackList
:const options = Object.fromEntries(Array.from(select, n => [ n.innerText, n ]));
select.prepend(...blackList.reduce((acc, n) => ((n = options[n]) && acc.push(n), acc), []));
select.append(...Array.prototype.filter.call(select, function(n) {
return !this.has(n.textContent);
}, new Set(blackList)));
$('form').on('input', function() {
const disabled = $('[type="text"]', this).get().some(n => n.value.length < 5);
$('[type="submit"]', this).prop({ disabled });
});
document.querySelector('form').addEventListener('input', e => {
e.currentTarget.querySelector('[type="submit"]').disabled = Array
.from(e.currentTarget.querySelectorAll('[type="text"]'))
.some(n => n.value.length < 5);
});