const parent = document.querySelector('.parent');
const toWrapClass = 'child';
const wrapperTag = 'div';
const wrapperClass = 'wrapper';
[...parent.children].reduce((wrapper, n) => {
if (n.classList.contains(toWrapClass)) {
if (!wrapper) {
wrapper = document.createElement(wrapperTag);
wrapper.classList.add(wrapperClass);
n.before(wrapper);
}
wrapper.appendChild(n);
return wrapper;
}
return null;
}, null);
Array.prototype.reduce.call(
parent.querySelectorAll(`:scope > .${toWrapClass}`),
(acc, n, i, a) => (
n.previousElementSibling !== a[i - 1] && acc.push([]),
acc.at(-1).push(n),
acc
),
[]
).forEach(n => {
const wrapper = document.createElement(wrapperTag);
wrapper.className = wrapperClass;
parent.insertBefore(wrapper, n[0]);
wrapper.append(...n);
});
const toWrapSelector = `.${toWrapClass}`;
const wrapperHTML = `<${wrapperTag} class="${wrapperClass}"></${wrapperTag}>`;
for (
let curr = parent.firstElementChild, next = null, prev = null, wrapper = null;
next = curr?.nextElementSibling, curr;
prev = curr, curr = next
) {
if (!curr.matches(toWrapSelector)) {
continue;
}
if (!prev?.matches(toWrapSelector)) {
curr.insertAdjacentHTML('beforebegin', wrapperHTML);
wrapper = curr.previousSibling;
}
wrapper.insertAdjacentElement('beforeend', curr);
}
import { useSlots, computed } from 'vue';
const slots = useSlots();
const columns = computed(() => slots.default?.().filter(n => n.props));
<table>
<thead>
<tr>
<th v-for="{ props: p, children: c } in columns" :key="p.prop">
<component v-if="c?.header" :is="c.header" />
<template v-else>{{ p.label }}</template>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in data">
<td v-for="{ props: p, children: c } in columns" :key="p.prop">
<component v-if="c?.body" :is="c.body" :row="row" />
<template v-else>{{ row[p.prop] }}</template>
</td>
</tr>
</tbody>
</table>
при изменении language у меня не меняются переводы
texts
обновляется в эффекте, т.е., после того, как новая версия t
будет создана. Так что t
получает ссылку на старую версию texts
.texts
не надо, доставайте в t
нужный объект из translations
напрямую:const t = useCallback(
key => key
.split('.')
.reduce((p, c) => p?.[c], translations[language]),
[ language ]
);
filter
(а ещё Safari - говорят, яблочные уроды пока не реализовали поддержку методов итераторов; впрочем, сделать обычный for...of
вместо reduce
не проблема):function countIntersections(data1, data2, key = n => n) {
const getKey = key instanceof Function ? key : n => n[key];
const keys = new Set(Array.from(data2, getKey));
return data1[Symbol.iterator]().reduce((acc, n) => acc + keys.has(getKey(n)), 0);
}
const result = countIntersections(newWord, glas);
.countIntersections(Array(7).keys(), Array(4).keys()) // 4
countIntersections('abCdE', 'ACe', n => n.toLowerCase()) // 3
countIntersections([ { id: 1 }, { id: 2 }, { id: 3 } ], [ { id: 3 } ], 'id') // 1
- app.component('draggable', window['vue3-draggable']);
+ app.component('draggable', window['vue3-draggable'].default);
$result = [];
foreach ($arr as $n) {
for ($visited = []; array_key_exists($n, $arr); $visited[] = $n, $n = $arr[$n]) {
if (($i = array_search($n, $visited)) !== false) {
$loop = array_slice($visited, $i);
if (empty(array_intersect(array_column($result, 0), $loop))) {
$result[] = $loop;
}
break;
}
}
}
$result = [];
$visited = [];
$iLoop = -1;
foreach ($arr as $n) {
for ($iLoop++; isset($arr[$n]); $visited[$n] = $iLoop, $n = $arr[$n]) {
if (isset($visited[$n])) {
if ($visited[$n] === $iLoop) {
for ($loop = [ $m = $n ]; ($m = $arr[$m]) !== $n; $loop[] = $m) ;
$result[] = $loop;
}
break;
}
}
}
$grouped = [];
foreach ($arr as [ 'id' => $id, 'name' => $name, 'key' => $key ]) {
$grouped[$key][$name] ??= [ 'name' => $name, 'ids' => [] ];
$grouped[$key][$name]['ids'][] = $id;
}
foreach ($keys as $k) {
$$k = array_map(fn($n) => [
'name' => $n['name'],
'ids' => implode(', ', $n['ids'])
], array_values($grouped[$k] ?? []));
}
// такого у вас сейчас нет, сами догадайтесь, кому надо класс добавить
const containerSelector = '.container';
const buttonsSelector = `${containerSelector} .filter__navigation`;
const buttonSelector = `${buttonsSelector} [data-filter]`;
const buttonActiveClass = '_active';
const itemsSelector = `${containerSelector} .search__body`;
const itemSelector = `${itemsSelector} .filter-column`;
const itemHiddenClass = '_hide';
const itemFilterClassPrefix = 'filter__column_';
document.querySelectorAll(buttonSelector).forEach(n => {
n.addEventListener('click', onFilterButtonClick);
});
function onFilterButtonClick({ currentTarget: { dataset: { filter } } }) {
const activeItemClass = itemFilterClassPrefix + filter;
this.closest(buttonsSelector).querySelectorAll(buttonSelector).forEach(n => {
n.classList.toggle(buttonActiveClass, n === this);
});
this.closest(containerSelector).querySelectorAll(itemSelector).forEach(({ classList: cl }) => {
cl.toggle(itemHiddenClass, filter !== 'all' && !cl.contains(activeItemClass));
})
}
document.addEventListener('click', e => {
const button = e.target.closest(buttonSelector);
if (button) {
const { filter } = button.dataset;
const activeItemSelector = filter === 'all' ? '*' : `.${itemFilterClassPrefix}${filter}`;
for (const n of button.closest(buttonsSelector).children) {
n.classList.toggle(buttonActiveClass, n === button);
}
for (const n of button.closest(containerSelector).querySelector(itemsSelector).children) {
n.classList.toggle(itemHiddenClass, !n.matches(activeItemSelector));
}
}
});
{ 'старый ключ': 'новый ключ' }
:const keys = {
x: 'a',
y: 'b',
z: 'c',
};
const renameKeys = (obj, keys) =>
Object.fromEntries(Object
.entries(obj)
.map(([ k, v ]) => [ Object.hasOwn(keys, k) ? keys[k] : k, v ])
);
// или
const renameKeys = (obj, keys) =>
Object.keys(obj).reduce((acc, k) => (
acc[keys[k] ?? k] = obj[k],
acc
), {});
const newArr = arr.map(n => renameKeys(n, keys));
function renameKeys(keys, obj) {
for (const k in keys) {
if (obj.hasOwnProperty(k)) {
obj[keys[k]] = obj[k];
delete obj[k];
}
}
}
arr.forEach(renameKeys.bind(null, keys));
элемент.insertAdjacentHTML('afterend', разметка);
элемент.remove();
// или
элемент.outerHTML = разметка;
<el-table
ref="table"
...
>
...
const table = ref();
onMounted(() => {
new Sortable(table.value.$el.querySelector('thead tr'), {
handle: 'span',
onEnd(e) {
columns.value.splice(e.newIndex, 0, columns.value.splice(e.oldIndex, 1)[0]);
},
});
});
colors: markerColors, // Устанавливаем цвета маркеров в зависимости от результата
discrete
, позволяющим индивидуально настраивать внешний вид каждого маркера. Всплывающую подсказку это никак не затрагивает, так что её придётся кастомизировать отдельно. function bindRootContext(obj, context = obj) {
return new Proxy(obj, {
get(target, key) {
const val = target[key];
return (
val instanceof Function ? val.bind(Object.hasOwn(target, key) ? context : target) :
val instanceof Object ? bindRootContext(val, context) :
val
);
},
});
}
const obj = bindRootContext({
name: 'Root',
a: {
name: 'A',
logName() { console.log(this.name); },
b: {
name: 'B',
logName() { console.log(this.name); },
arr: [
{
name: '666',
logName() { console.log(this.name); },
},
function() { console.log(this.name); },
],
c: {
name: 'C',
logName() { console.log(this.name); },
},
},
},
});
obj.a.b.c.logName(); // Root
obj.a.b.logName(); // Root
obj.a.logName(); // Root
obj.a.b.arr[0].logName(); // Root
obj.a.b.arr[1](); // Root
Можно ли пользоваться структурами данных из SDK при решении алгоритмических секций?
читинг или норм решение?
mergedList.sort()
кнопка.addEventListener('click', () => {
const [ li ] = шаблон.content.cloneNode(true).children;
li.querySelector('.card__image').src = инпут_с_ссылкой.value;
li.querySelector('.card__title').textContent = инпут_с_подписью.value;
список.insertAdjacentElement('afterbegin', li);
// или
список.prepend(document.importNode(шаблон.content, true));
список.querySelector('img').setAttribute('src', инпут_с_ссылкой.value);
список.querySelector('h2').innerText = инпут_с_подписью.value;
});
const columns = [ 'name', 'age', 'id' ];
.res.innerHTML = `
<table>
<thead>
<tr>${columns.map(n => `<th>${n}</th>`).join('')}</tr>
</thead>
<tbody>${arr[0]?.map((_, i) => `
<tr>${arr.map(n => `
<td>${n[i]}</td>`).join('')}
</tr>`).join('') ?? ''}
</tbody>
</table>`;
const table = document.createElement('table');
columns.forEach(function(n) {
this.append(document.createElement('th'));
this.lastChild.textContent = n;
}, table.createTHead().insertRow());
arr[0]?.forEach(function(_, i) {
const tr = this.insertRow();
arr.forEach(n => tr.insertCell().textContent = n[i]);
}, table.createTBody());
res.append(table);