Задать вопрос
  • Как найти и сгруппировать элементы с одинаковым классом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где, кого и во что надо обернуть:

    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);
    }
    Ответ написан
    1 комментарий
  • Как отрисовать дочерние slots в родительском компоненте?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вот так:

    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>
    Ответ написан
    1 комментарий
  • Как обновлять дочерние элементы которые принимают значение функции?

    0xD34F
    @0xD34F Куратор тега React
    при изменении language у меня не меняются переводы

    Меняются. С запаздыванием на один шаг. Потому что texts обновляется в эффекте, т.е., после того, как новая версия t будет создана. Так что t получает ссылку на старую версию texts.

    Никакого texts не надо, доставайте в t нужный объект из translations напрямую:

    const t = useCallback(
      key => key
        .split('.')
        .reduce((p, c) => p?.[c], translations[language]),
      [ language ]
    );
    Ответ написан
    Комментировать
  • Как посчитать количество пересечений с помощью метода filter?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Решим задачу в общем виде - сделаем функцию, находящую количество совпадающих элементов у любых итерируемых объектов. Причём под совпадением будем понимать не обязательно непосредственное равенство (оставим это как вариант по умолчанию), а равенство некоторых производных значений. Так что к чёрту 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
    Ответ написан
    Комментировать
  • Как использовать компонент vue3-draggable без сборщиков?

    0xD34F
    @0xD34F Куратор тега Vue.js
    - app.component('draggable', window['vue3-draggable']);
    + app.component('draggable', window['vue3-draggable'].default);
    Ответ написан
  • Как найти циклы в массиве?

    0xD34F
    @0xD34F
    Вот говнокод:

    $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;
        }
      }
    }
    Ответ написан
    Комментировать
  • Как найти сумму элементов словарей со значениями кортежами, вложенных в список?

    0xD34F
    @0xD34F
    result = 0
    
    for n in lst:
      for m in n.values():
        for val in m:
          result += val

    или

    result = sum(val for n in lst for m in n for val in n[m])
    Ответ написан
    Комментировать
  • Как разбить многомерный массив на несколько по ключам?

    0xD34F
    @0xD34F
    $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] ?? []));
    }
    Ответ написан
    1 комментарий
  • Как применить js код к своему блоку?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Куда кликаем и что фильтруем:

    // такого у вас сейчас нет, сами догадайтесь, кому надо класс добавить
    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));
        }
      }
    });
    Ответ написан
    Комментировать
  • Как изменить набор ключей в массиве?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кого на что меняем, объект вида { 'старый ключ': 'новый ключ' }:

    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));
    Ответ написан
    Комментировать
  • Какие короткие ссылки можно использовать на qna.habr.com?

    0xD34F
    @0xD34F
    полагаю это техническая ошибка и её нужно исправить

    Это сюда. Тема - "Ошибка в работе сайта".

    Или же пересмотреть правила

    Туда же. Только подавайте как гениальную идею.
    Ответ написан
    1 комментарий
  • Как эффективно заменить текущий HTML элемент на другой?

    0xD34F
    @0xD34F Куратор тега JavaScript
    элемент.insertAdjacentHTML('afterend', разметка);
    элемент.remove();
    
    // или
    
    элемент.outerHTML = разметка;
    Ответ написан
    4 комментария
  • Как сделать так чтобы колонки в таблице Element Plus были draggable?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Можно попробовать использовать sortable.js:

    <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]);
        },
      });
    });
    Ответ написан
  • Как в Apex Charts покрасить маркеры на графике в зависимости от значения?

    0xD34F
    @0xD34F Куратор тега JavaScript
    colors: markerColors, // Устанавливаем цвета маркеров в зависимости от результата

    Эта настройка предназначена для назначения цветов не отдельных маркеров, а относящихся к одному набору данных. Так что, чтобы заработало так, как вы хотите, придётся данные разделить. После чего использовать эту настройку станет уже необязательно - цвета можно задавать непосредственно внутри наборов данных. Недостаток - общей линией точки на графике не будут соединены.

    Другой вариант - воспользоваться свойством discrete, позволяющим индивидуально настраивать внешний вид каждого маркера. Всплывающую подсказку это никак не затрагивает, так что её придётся кастомизировать отдельно.
    Ответ написан
    Комментировать
  • Как создать объект с контекстом родительского объекта?

    0xD34F
    @0xD34F Куратор тега JavaScript
    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
    Ответ написан
    1 комментарий
  • Можно ли пользоваться структурами данных из SDK при решении алгоритмических секций?

    0xD34F
    @0xD34F
    Можно ли пользоваться структурами данных из SDK при решении алгоритмических секций?

    Ваша цель какая? Решить задачу, и ничего больше - решайте как получится. Разобраться, как эти структуры устроены - реализовывайте их самостоятельно.

    читинг или норм решение?

    Да конечно "читинг". Но по другой причине:

    mergedList.sort()

    То решение, которое от вас тут ожидается, не предполагает применения сортировки - ни встроенной, ни вручную.
    Ответ написан
    Комментировать
  • Как вывести на страницу карточки с картинкой, ссылка на которую указываю в модальном окне input?

    0xD34F
    @0xD34F Куратор тега JavaScript
    кнопка.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;
    });
    Ответ написан
  • Как вывести сложный объект на график в DevExtreme Angular 17?

    0xD34F
    @0xD34F
    Надо найти в документации пример нужного вам графика, посмотреть, в каком виде следует подавать в него данные, привести свои данные к этому виду. Всё.
    Ответ написан
  • Как добавить событие фокуса на динамические элементы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    К чёрту focus, используйте focusin, оно всплывает, в отличие от.
    Ответ написан
    Комментировать
  • Как обработать многомерный массив для вывода определенных парных значений?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сделаем таблицу. Какие у неё будут столбцы: 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);
    Ответ написан
    Комментировать