Задать вопрос
  • Как изменить цвет ссылки при наличии в ней определённого текста?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кого будем перекрашивать, и в какие цвета:

    const className = 'some-link';
    const colors = {
      En:   'red',
      Ru: 'green',
      De:  'blue',
    };

    Перекрашиваем текст в случае точного совпадения:

    for (const n of document.getElementsByClassName(className)) {
      n.style.color = colors[n.textContent];
    }

    Или, смотрим наличие подстроки, регистр не важен:

    document.querySelectorAll(`.${className}`).forEach(function(n) {
      n.style.color = this.find(m => m[0].test(n.innerText))?.[1];
    }, Object.entries(colors).map(n => [ RegExp(n[0], 'i'), n[1] ]));

    Можно и без регулярных выражений:

    - RegExp(n[0], 'i')
    + n[0].toLowerCase()

    - m[0].test(n.innerText)
    + n.innerText.toLowerCase().includes(m[0])
    Ответ написан
    Комментировать
  • Как записать рекурсию (функц. глубокого копирования) в виде цикла?

    0xD34F
    @0xD34F
    Используйте стек.

    Если, обрабатывая данные, натыкаетесь на объект, надо сохранить в стек текущее состояние - ссылку на копируемые данные, индекс текущего элемента, ссылку на объект, куда копируете; затем установить новое состояние - копируемыми данными будет массив пар ключ-значение встреченного объекта, индекс обнуляется (на самом деле надо выставить -1, нулевое значение будет получено при переходе к следующей итерации; конечно, можно и буквально 0 выставлять, но тогда придётся усложнить работу с индексом - тут увеличиваем, а тут нет), пустой объект в качестве копии.

    Если данные закончились, надо восстановить состояние из стека.

    Условий, при которых возможно продолжение цикла, будет два - кроме наличия необработанных данных ещё и непустой стек.

    function clone(value) {
      const clone = {};
      const stack = [];
    
      for (
        let i = 0, source = [ [ '', value ] ], target = clone;
        i < source.length || stack.length;
        i++
      ) {
        if (i === source.length) {
          [ i, source, target ] = stack.pop();
        } else {
          const [ k, v ] = source[i];
          const isObject = v instanceof Object;
    
          target[k] = isObject ? v.constructor() : v;
    
          if (isObject) {
            stack.push([ i, source, target ]);
            [ i, source, target ] = [ -1, Object.entries(v), target[k] ];
          }
        }
      }
    
      return clone[''];
    }

    Или, если в копируемом объекте могут быть циклические ссылки или какой-то из вложенных объектов встречается несколько раз и так же должно быть и в копии, то надо запоминать встреченные объекты, чтобы не обрабатывать их повторно - воспользуемся Map'ом, где ключами будут оригинальные объекты, а значениями их копии.

    Как выглядит получение копии объекта: проверяем, встречался ли указанный объект ранее, если нет - создаём новый объект, сохраняем его в Map, а также кладём его вместе с оригиналом в стек, для последующей обработки; достаём из Map'а копию.

    Крутим цикл, пока стек не пуст, на каждой итерации достаём из стека объект и его копию, перебираем свойства оригинала, записываем в копию копии значений.

    function clone(value) {
      const stack = [];
      const clones = new Map;
      const getClone = val => val instanceof Object
        ? (clones.has(val) || stack.push([ val, clones.set(val, val.constructor()).get(val) ]),
           clones.get(val))
        : val;
    
      for (getClone(value); stack.length;) {
        const [ source, target ] = stack.pop();
        Object.entries(source).forEach(n => target[n[0]] = getClone(n[1]));
      }
    
      return getClone(value);
    }

    как правильнее всего будет это сделать?

    Перестать заниматься ерундой и начать использовать готовые решения - structuredClone или cloneDeep, например.
    Ответ написан
    Комментировать
  • Как в библиотеке chart.js указать в оси Y два значение (минимальное и максимальное)?

    0xD34F
    @0xD34F
    options: {
      scales: {
        y: {
          ticks: {
            callback: (value, index, values) =>
              index > 0 && index < values.length - 1
                ? ''
                : Math[index ? 'max' : 'min'](...values.map(n => n.value)),
            ...
    Ответ написан
    2 комментария
  • Задать класс body при активной переменной во vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    watch: {
      переменная: {
        immediate: true,
        handler(val) {
          document.body.classList.toggle('класс', val);
        },
      },
    },
    Ответ написан
    Комментировать
  • Почему style background vue3 не применяется?

    0xD34F
    @0xD34F Куратор тега Vue.js
    нужно создать 6 блоков с разными цветами

    :style="{ color: bgColor }"

    Цветами ЧЕГО? Свойство color - это цвет текста, никакого текстового содержимого в блоках нет.

    Делаю как в документации

    v-for="(index, bgColor) in colorArray"

    Ну конечно, как в документации. Там ведь тоже элемент массива и его индекс местами перепутаны. Или всё-таки нет?
    Ответ написан
    Комментировать
  • Как написать этот код легче?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const newData = data.reduce((acc, n) => {
      const k = Object.keys(n)[0];
      (acc.result[acc.keys[k] = (acc.keys[k] ?? -1) + 1] ??= []).push(n);
      return acc;
    }, { result: [], keys: {} }).result.flat();

    или

    const numKeys = new Set(data.flatMap(Object.keys)).size;
    const numObjs = data.length / numKeys;
    const newData = data.map((n, i, a) => a[(i % numKeys) * numObjs + (i / numKeys | 0)]);
    Ответ написан
    2 комментария
  • Если в диве больше 1го элемента то добавить класс к диву?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кому надо добавить класс, какой класс, сколько вложенных элементов должно быть:

    const selector = 'селектор элементов';
    const className = 'класс';
    const minChildrenCount = 666;

    Добавляем:

    for (const n of document.querySelectorAll(selector)) {
      n.classList.toggle(className, n.children.length >= minChildrenCount);
    }
    
    // или (нет, так делать точно не надо - для 0 результат будет некорректным)
    
    document
      .querySelectorAll(`${selector} > :nth-child(${minChildrenCount})`)
      .forEach(n => n.parentNode.classList.add(className));
    Ответ написан
    Комментировать
  • Одномерный массив в многомерный?

    0xD34F
    @0xD34F Куратор тега JavaScript
    (function toArrays(obj) {
      const arr = Object.values(obj ?? {});
      arr.forEach(n => n.children = toArrays(n.children));
      return arr;
    })(arr.reduce((acc, n) => {
      const path = n.path.replace(/^\/|\/$/g, '').split('/');
      const obj = path.reduce((p, c) => ((p.children ??= {})[c] ??= {}), acc);
      Object.assign(obj, n);
      return acc;
    }, {}).children)
    Ответ написан
    2 комментария
  • Выбор из нескольких компонентов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      component() {
        /*
         * здесь возвращаете имя компонента, в зависимости от... это вам виднее;
         * если действительно будет так, как показано в вопросе - натуральные числа
         * соответствуют компонентам, то можно сложить имена компонентов в массив:
         * return [ 'component-1', 'component-2', 'component-3' ][this.x - 1];
         */
      },
    },

    <component :is="component" />
    Ответ написан
    1 комментарий
  • Как сделать подсчет количества строк?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      linesCount() {
        return 1 + (this.text.match(/\n/g)?.length ?? 0);
      },
    },

    <div>{{ linesCount }}</div>
    Ответ написан
    1 комментарий
  • Как переписать функцию со scrollIntoView?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Задать связь между кнопками и блоками с помощью data-атрибутов:

    <div class="mainMenu">
      <button data-scroll-to="calendar">Раз</button>
      <button data-scroll-to="rooms">Два</button>
      <button data-scroll-to="maps">Три</button>
      <button data-scroll-to="contact">Четыре</button>
    </div>
    ...
    <div data-block="calendar">...</div>
    <div data-block="rooms">...</div>
    <div data-block="maps">...</div>
    <div data-block="contact">...</div>

    Сделать функцию, которая получает значение атрибута, находит соответствующий блок и выполняет прокрутку:

    function scrollTo(block) {
      document.querySelector(`[data-block="${block}"]`).scrollIntoView({
        block: 'center',
        behavior: 'smooth',
      });
    }

    Воспользоваться этой функцией при обработке кликов по кнопкам:

    document.querySelector('.mainMenu').addEventListener('click', e => {
      const block = e.target.dataset.scrollTo;
      if (block) {
        scrollTo(block);
      }
    });
    
    // или
    
    document.querySelectorAll('[data-scroll-to]').forEach(function(n) {
      n.addEventListener('click', this);
    }, e => scrollTo(e.target.dataset.scrollTo));
    Ответ написан
    1 комментарий
  • Как сделать алгоритм добавления елементов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Значения в массиве строк уникальны? Если нет, сколько надо добавлять объектов?

    Сколько раз строка повторилась - столько новых объектов будет добавлено:

    const names = new Set(objects.map(n => n.name));
    strings.forEach(n => (names.has(n) || objects.push({ name: n })));

    Два раза одно и то же не добавляем:

    new Set(strings).forEach(function(n) {
      if (!this.has(n)) {
        objects.push({ name: n });
      }
    }, new Set(objects.map(n => n.name)));
    
    // или
    
    for (const name of strings) {
      if (objects.every(n => n.name !== name)) {
        objects[objects.length] = { name };
      }
    }
    
    // или
    
    objects.splice(0, objects.length, ...strings.reduce(
      (acc, n) => acc.set(n, acc.get(n) ?? { name: n }),
      new Map(objects.map(n => [ n.name, n ]))
    ).values());
    Ответ написан
    Комментировать
  • Как в списке удалить весь текст выше 3-рёх подряд строк заканчивающихся на знаки препинания в конце?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const punct = '.,!?;:"\'”“';
    const numStrWithPunctEnd = 3;
    const arr = str.split('\n');
    const index = arr.findIndex(function(n, i, a) {
      return this.every(m => punct.includes(a[i + m]?.slice(-1)));
    }, [...Array(numStrWithPunctEnd).keys()]);
    const result = index !== -1 ? arr.slice(index).join('\n') : str;
    Ответ написан
  • Регулярное выражение находящее текст после n-го значения подстроки?

    0xD34F
    @0xD34F
    results = re.findall(r'(?<=SELECT).+?(?=FROM)', string, re.I | re.DOTALL)
    print(results[2])
    Ответ написан
    Комментировать
  • Почему неправильно парсится дата?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Число перепутано с днём недели; не добавлена единица номеру месяца (они с нуля начинаются).

    Ну и сам формат не везде поддерживается - в фаерфоксе получите Invalid Date. Выдирайте из строки компоненты даты и засовывайте их в конструктор по отдельности, или воспользуйтесь какой-нибудь готовой библиотекой для работы с датами.
    Ответ написан
  • Можно ли передать параметр в computed vue3?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Можно. Если значение этого computed является функцией. Но если вам туда надо передавать параметр, то, наверное, это должен быть метод, а не computed.
    Ответ написан
    Комментировать
  • Как отслеживать смену значений в объекте?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Заворачиваете свой объект в Proxy:

    const obj = {
      a: 69,
      b: 187,
      c: 666,
    };
    
    const proxy = new Proxy(obj, {
      set(target, key, val) {
        console.log('свойство', key, 'изменило своё значение с', target[key], 'на', val);
        target[key] = val;
        return true;
      },
    });

    Дальше вместо исходного объекта работаете с экземпляром Proxy.
    Ответ написан
    2 комментария
  • Как правильно свести посты к категориям, через отношение?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      categories() {
        return this.posts.data.reduce((acc, n) => (
          (acc[n.category_name] ??= {
            name: n.category_name,
            posts: [],
          }).posts.push(...n.posts),
          acc
        ), {});
      },
      ...

    <div v-for="category in categories">
      <h3>{{ category.name }}</h3>
      <div v-for="post in category.posts">
        {{ post.title }}
      </div>
    </div>
    Ответ написан
  • JavaScript для новичков?

    0xD34F
    @0xD34F
    Нет, не для новичков.

    С чего начать изучение языка?

    Вопрос, конечно, невероятно уникальный. Сам факт задавания такого вопроса живым людям вместо поисковой системы ясно свидетельствует, что начинать не надо. Пустая трата времени. Раз не хватило мозгов, чтобы погуглить, то и на язык не хватит. Программирование не для вас.
    Ответ написан
    8 комментариев