computed: {
filteredProducts() {
const keyword = this.keyword.toLowerCase();
return this.products.filter(item => (
(item.name.toLowerCase().includes(keyword)) &&
(!this.colors.length || this.colors.includes(item.color)) &&
(!this.sizes.length || this.sizes.some(n => item.size.includes(n))) &&
(!this.categories.length || this.categories.includes(item.category))
));
},
...
computed: {
colorFilter() {
return Array
.from(new Set(this.products.map(n => n.color)))
.sort((a, b) => a.localeCompare(b));
},
...
onChange = {(event, userItem)=>handleChange(event, userItem)}
onChange={e => handleChange(e, userItem)}
.onChange={handleChange.bind(userItem)}
,function handleChange(e) {
console.log('userItem', this);
console.log('value', e.target.value);
}
str[0] === str[0].toUpperCase()
/^[A-Z]/.test(str)
(c => 64 < c && c < 91)(str.charCodeAt(0))
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.includes(str.at(0))
from random import sample
arr = [ 'AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF', 'GGG', 'HHH' ]
string = ''.join(sample(arr, k=len(arr)))
$('.filter').change(({ target: t }) => {
$(`[name="${$(t).closest('.button').data('size')}"]`)
.closest('.product-box')
.toggleClass('hidden', !t.checked);
}).find(':checked').change();
const filter = document.querySelector('.filter');
filter.addEventListener('change', ({ target: t }) => {
const size = t.closest('.button').dataset.size;
document.querySelectorAll(`[name="${size}"]`).forEach(n => {
n.closest('.product-box').classList.toggle('hidden', !t.checked);
});
});
filter.querySelectorAll(':checked').forEach(n => {
n.dispatchEvent(new Event('change', { bubbles: true }));
});
const group = (arr, key) =>
arr.reduce((acc, n) => (
(acc[n[key]] = acc[n[key]] || []).push(n),
acc
), {});
const groupItemKeys = [ 'kurs', 'contract', 'credit' ];
const groupedData = useMemo(() => {
return Object.entries(group(data, 'country'));
}, [ data ]);
<tbody>{groupedData.map(([ country, items ], i) =>
<tr>
<td>{i + 1}</td>
<td>{country}</td>
{groupItemKeys.map(k =>
<td>{items.map(n => <div>{n[k]}</div>)}</td>
)}
</tr>)}
</tbody>
const groupedData = useMemo(() => {
return Object.values(group(data, 'country'));
}, [ data ]);
<tbody>{groupedData.map((n, i) => n.map((m, j) =>
<tr>
{!j && <React.Fragment>
<td rowSpan={n.length}>{i + 1}</td>
<td rowSpan={n.length}>{m.country}</td>
</React.Fragment>}
{groupItemKeys.map(k => <td>{m[k]}</td>)}
</tr>))}
</tbody>
const rowsData = useMemo(() => {
return Object
.values(group(data, 'country'))
.flatMap((items, i) => items.map((n, j) => (j
? []
: [ i + 1, n.country ].map(m => [ m, items.length ])
).concat(groupItemKeys.map(k => [ n[k] ]))));
}, [ data ]);
<tbody>{rowsData.map(n =>
<tr>{n.map(m => (
<td rowSpan={m[1]}>{m[0]}</td>))}
</tr>)}
</tbody>
<div>
<input id="password">
</div>
<div>
<div>Сложность пароля: <span id="strength_percent">0</span>%</div>
<progress id="strength_progress" max="100" value="0"></progress>
</div>
<div id="errors"></div>
const validations = [
{
test: val => val.length >= 8,
message: 'пароль должен содержать хотя бы 8 символов',
},
{
test: val => /[A-ZА-ЯЁ]/.test(val),
message: 'пароль должен содержать хотя бы 1 большую букву',
},
{
test: val => /[a-zа-яё]/.test(val),
message: 'пароль должен содержать хотя бы 1 маленькую букву',
},
{
test: val => /[^\s\da-zа-яё]/i.test(val),
message: 'пароль должен содержать хотя бы 1 специальный символ (не пробел, букву или цифру)',
},
{
test: val => /\d/.test(val),
message: 'пароль должен содержать хотя бы 1 цифру',
},
];
document.querySelector('#password').addEventListener('input', ({ target: { value } }) => {
const errors = validations.reduce((acc, n) => (
n.test(value) || acc.push(n.message),
acc
), []);
const strength = (validations.length - errors.length) / validations.length * 100;
document.querySelector('#strength_progress').value = strength;
document.querySelector('#strength_percent').innerText = strength | 0;
document.querySelector('#errors').innerHTML = errors
.map(n => `<p>${n}</p>`)
.join('');
});
оборачивается не полностью
childNodes
представляет собой динамическую коллекцию, т.е., при добавлении или удалении узлов она обновляется без каких-либо действий с вашей стороны. Поэтому, когда вы добавляете в wrapper
нулевой узел, он тут же пропадает из item.childNodes
, а у оставшихся узлов позиция уменьшается на единицу - тот, что был первым, становится нулевым, второй первым и так далее. Так что когда for...of
переходит к следующему узлу, им оказывается не тот, что изначально имел индекс 1
, а расположенный за ним. Бывший первый, а теперь нулевой, оказывается пропущен. Аналогичным образом будут пропущены и все последующие узлы, изначально имевшие нечётные индексы.while (item.childNodes.length) {
wrapper.appendChild(item.childNodes[0]);
}
childNodes
от конца к началу:for (let i = item.childNodes.length; i--;) {
wrapper.prepend(item.childNodes[i]);
}
childNodes
, а массив:for (const n of [...item.childNodes]) {
wrapper.append(n);
}
append
может принимать несколько параметров, так что переносим сразу всё:document.querySelectorAll('.www').forEach(n => {
const wrapper = document.createElement('div');
wrapper.classList.add('red');
wrapper.append(...n.childNodes);
n.append(wrapper);
});
for (const n of document.getElementsByClassName('www')) {
n.innerHTML = `<div class="red">${n.innerHTML}</div>`;
}
computed: {
summary() {
return (this.choosenSize?.cost ?? 0) + this.choosenTopping.reduce((acc, n) => acc + n.cost, 0);
},
},
from random import choice
chars = '0123456789abcdefghijklmnopqrstuvwxyz'
section_size = 4
sections_num = 5
string = '-'.join(''.join(choice(chars) for j in range(section_size)) for i in range(sections_num))
const sorted = arr
.map(n => [
n,
+new URLSearchParams(n.querySelector('a').href.split('?').pop()).get('value') || Infinity,
])
.sort((a, b) => a[1] - b[1])
.map(n => n[0]);
parentEl.append(...Array
.from(parentEl.querySelectorAll('a'), n => [
n.parentNode,
Number(n.getAttribute('href').match(/(?<=value=)\d+/)) || Infinity,
])
.sort((a, b) => a[1] - b[1])
.map(n => n[0])
);
const Figure = ({ type, ...props }) => <div className={type} {...props}></div>;
class App extends React.Component {
state = {
types: [ 'circle', 'square', 'triangle' ],
figures: [],
}
add(type) {
this.setState(({ figures }) => ({
figures: [ ...figures, type ],
}));
}
render() {
const { types, figures } = this.state;
return (
<div>
<div>
{types.map(n => <Figure type={n} onClick={() => this.add(n)} />)}
</div>
<div>
{figures.map(n => <Figure type={n} />)}
</div>
</div>
);
}
}
function Preloader({ Tag = 'h1', children }) {
return (
<Tag className={s.wrapper}>
<div className={s.preloader}></div>
{children}
</Tag>
);
}
<div className="App">
<Preloader>hello, world!!</Preloader>
<Preloader Tag="h2">fuck the world</Preloader>
</div>