элемент.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;
});
data: () => ({
active: [ 0, -1 ],
...
methods: {
onKeyDown(e) {
const { items } = this;
const step = ({
ArrowUp: -1,
ArrowDown: 1,
})[e.key];
if (step && items.some(n => n.children?.length)) {
let iItem = this.active[0];
let iChild = this.active[1] + step;
while (!items[iItem].children?.[iChild]) {
iItem = (iItem + step + items.length) % items.length;
iChild = step === 1 ? 0 : ~-items[iItem].children?.length;
}
this.active = [ iItem, iChild ];
}
},
...
<ul>
<li v-for="(item, iItem) in items">
<ul>
<li
v-for="(child, iChild) in item.children"
:class="{ active: active[0] === iItem && active[1] === iChild }"
...
computed: {
children() {
return this.items.flatMap(n => n.children ?? []);
},
...
data: () => ({
active: null,
...
methods: {
onKeyDown({ key }) {
const { length } = this.children;
const step =
key === 'ArrowUp' ? -1 :
key === 'ArrowDown' ? 1 :
0;
if (step && length) {
const active = this.active ?? (step === 1 ? -1 : length);
this.active = Math.max(0, Math.min(length - 1, active + step));
}
},
...
<ul>
<li v-for="item in items">
<ul>
<li
v-for="child in item.children"
:class="{ active: children[active] === child }"
...
чтобы данные не терялись
v-for
назначаем элементу списка класс, который его визуально выделит. Как-то так. const filteredProducts = computed(() => {
const search = searchQuery.value.toLowerCase();
return search.length > 2
? data.value.filter(n => n.title.toLowerCase().includes(search))
: null;
});
<ul v-if="filteredProducts" class="search-result">
<li v-if="!filteredProducts.length">
<h3>ничего не найдено</h3>
</li>
<li v-for="n in filteredProducts">
<div>
<Image :src="n.image" :alt="n.title" width="40" height="40" />
</div>
<h3>{{ n.title }}</h3>
<div>
<p>{{ n.price }}</p>
</div>
</li>
</ul>
v-for
.// если гарантируется отсутствие thead и tfoot, или их содержимое также должно учитываться
const { rows } = table;
// если tbody один
const [ { rows } ] = table.tBodies;
// если tbody несколько
const rows = Array.prototype.flatMap.call(table.tBodies, n => [...n.rows]);
// или
const rows = [].concat(...Array.from(table.tBodies, n => [...n.children]));
// или
const rows = table.querySelectorAll('tbody tr');
const middle = arr => arr[arr.length >> 1];
// или
const middle = arr => arr[Math.floor(arr.length / 2)];
// или
const middle = arr => arr[Math.round(~-arr.length / 2)];
// или
const middle = arr => arr[(arr.length - arr.length % 2) / 2];
const cell = middle(middle(rows).cells);
// или
const cell = middle([].reduce.call(rows, (acc, n) => (acc.push(...n.children), acc), []));
// или, без получения строк
const cell = middle(table.querySelectorAll('tbody td'));
const el = document.querySelector('p');
const strings = [ 'hello, world!!', 'fuck the world', 'fuck everything' ];
const delay = 100;
function Typewriter(el, strings, delay) {
let i = 0;
let length = 0;
return setInterval(() => {
if (++length > strings[i].length) {
i = -~i % strings.length;
length = 0;
}
el.textContent = strings[i].slice(0, length);
}, delay);
}
const intervalId = Typewriter(el, strings, delay);
// хотим остановить, делаем так: clearInterval(intervalId);
function Typewriter(el, strings, delay) {
let timeoutId = null;
(function step(i, length) {
length = -~length % -~strings[i].length;
i = (i + !length) % strings.length;
el.innerText = strings[i].substring(0, length);
timeoutId = setTimeout(step, delay, i, length);
})(0, 0);
return () => clearTimeout(timeoutId);
}
const stop = Typewriter(el, strings, delay);
// хотим остановить, делаем так: stop();
При повторном нажатии на кнопку максимальным числом выскакивает число удалённого li.
remove
приведёт к исчезновению элемента из lis
? Искать максимальный элемент следует среди тех, что всё ещё присутствуют на странице, а не тех, что были изначально - то есть, или надо получать элементы непосредственно перед поиском, или коллекция элементов должна быть динамической.function max(data, key = n => n) {
const getVal = key instanceof Function ? key : n => n[key];
let result = [ void 0, -Infinity ];
for (const n of data) {
const val = getVal(n);
if (result[1] < val) {
result = [ n, val ];
}
}
return result[0];
}
document.querySelector('button').addEventListener('click', function(e) {
max(this, n => +n.textContent)?.remove();
e.target.disabled = !this.length;
}.bind(document.querySelector('ul').children));
map.setBehaviors(map.behaviors.filter(n => n !== 'drag'));