Ответы пользователя по тегу JavaScript
  • Какие знания требуются для js trainee?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Чё-то смеюсь. Раньше вы хотели быть джуном. То, что за прошедшие два с лишним года вы свои амбиции поумерили - это хорошо. Правда, не до конца - ну да это ничего, ещё через два года наверняка дозреете до осознания того факта, что не бывать вам программистом. Отсюда кстати и ответ на непосредственно заданный вопрос - вам никакие знания не требуются. Успокойтесь, и идите работать в такси.
    Ответ написан
    2 комментария
  • Double Linked List, почему функция не отрабаывает и как организовать remove?

    0xD34F
    @0xD34F Куратор тега JavaScript
    На вопрос "почему не отрабатывает" ответ смотрите в консоли - там есть соответствующее сообщение об ошибке.

    class DoublyLinkedList {
      constructor() {
        this.size = 0;
        this.head = null;
        this.tail = null;
      }
    
      add(value, index) {
        index ??= this.size;
    
        const next = this.searchByIndex(index);
        const prev = next ? next.prev : this.tail;
        const node = { value, next, prev };
    
        prev || (this.head = node);
        next || (this.tail = node);
    
        prev && (prev.next = node);
        next && (next.prev = node);
    
        this.size++;
      }
    
      _remove(node) {
        if (node) {
          node.prev || (this.head = node.next);
          node.next || (this.tail = node.prev);
    
          node.prev && (node.prev.next = node.next);
          node.next && (node.next.prev = node.prev);
    
          this.size--;
        }
      }
    
      removeByValue(value) {
        this._remove(this.searchByValue(value));
      }
    
      removeByIndex(index) {
        this._remove(this.searchByIndex(index, true));
      }
    
      searchByIndex(index, strict) {
        if (!(index >= 0 && index <= this.size - !!strict)) {
          throw 'invalid index';
        }
    
        let node = this.head;
    
        while (index--) {
          node = node.next;
        }
    
        return node;
      }
    
      searchByValue(value, startIndex = 0) {
        let node = this.searchByIndex(startIndex, true);
    
        while (node && node.value !== value) {
          node = node.next;
        }
    
        return node;
      }
    }
    Ответ написан
    Комментировать
  • Как сделать фильтрацию при помощи input type number?

    0xD34F
    @0xD34F Куратор тега JavaScript
    .hidden {
      display: none;
    }

    document.querySelector('input').addEventListener('input', e => {
      const val = +e.target.value;
    
      document.querySelectorAll('.word').forEach(n => {
        n.closest('.block').classList.toggle('hidden', +n.innerText < val);
      });
    });
    Ответ написан
    Комментировать
  • Как проверить существует ли приватный метод?

    0xD34F
    @0xD34F Куратор тега JavaScript
    try {
      eval('this.#' + name);
      return true;
    } catch(e) {
      return false;
    }
    Ответ написан
    1 комментарий
  • Как найти наибольшее значение по полю в объекте и вернуть его?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function max(data, key = n => n) {
      const getVal = key instanceof Function ? key : n => n[key];
    
      return Array.prototype.reduce.call(data, (max, n) => {
        const val = getVal(n);
        return max[0] > val ? max : [ val, n ];
      }, [ -Infinity, undefined ])[1];
    }
    
    
    const { text } = max(arr, n => n.text.length);
    const oldest = max(arr, 'age');
    Ответ написан
    Комментировать
  • Как удалить лишние столбцы в table с помощью jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const remove = {
      from: 5,
      exclude: [ 9, 10, 11 ],
    };
    
    $('table tr').each(function() {
      $(this)
        .children()
        .filter(i => i >= remove.from && !remove.exclude.includes(i))
        .remove();
    });
    Ответ написан
    2 комментария
  • Как получить массив чисел месяца вместе с днями недели?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function getWeekdaysOfMonth(year, month) {
      const date = new Date(year, --month, 1);
      const result = [];
    
      while (date.getMonth() === month) {
        result.push(date.toLocaleString('ru-RU', {
          month: 'long',
          day: 'numeric',
          weekday: 'long',
        }));
        date.setDate(date.getDate() + 1);
      }
    
      return result;
    }
    
    
    const weekdaysOfDecember2020 = getWeekdaysOfMonth(2020, 12);

    UPD. Вынесено из комментариев:

    но как поступить если я не хочу забирать дни недели из стандартного объекта. а взять из их своего массива?

    const weekdays = [
      'воскресенье',
      'это понедельник',
      'а это вторник',
      'конечно же среда',
      'четверг',
      'пятница - прямо после четверга',
      'суббота, рабочая неделя окончена',
    ];
    
    const getWeekdaysOfMonth = (year, month) => Array.from(
      { length: new Date(year, month--, 0).getDate() },
      (n, i) => {
        const d = new Date(year, month, i + 1);
        return d.toLocaleString('ru-RU', {
          month: 'long',
          day: 'numeric',
        }) + ', ' + weekdays[d.getDay()];
      });
    
    
    const weekdaysOfFebruary2021 = getWeekdaysOfMonth(2021, 2);
    Ответ написан
  • Как получить src из тега picture?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.querySelector('.products__body').addEventListener('click', e => {
      const item = e.target.closest('.card-preview__item');
      if (item) {
        e.preventDefault();
        const { srcset } = item.querySelector('source');
        item.closest('.card').querySelector('.card-head__image source').srcset = srcset;
      }
    });
    Ответ написан
    1 комментарий
  • Почему не отрабатывает событие?

    0xD34F
    @0xD34F Куратор тега JavaScript
    • tagName:

      For DOM trees which represent HTML documents, the returned tag name is always in the canonical upper-case form.

      А теперь посмотрите, что вы у себя написали:

      if(str.tagName == 'ul') {

      } else if (str.tagName == 'li') {

      Кстати, а почему str, что за странный выбор имени? Там же элемент, а не строка.

    • Вместо элемента добавляется строка:

      elem.append('li');

    • Крайне странное назначение обработчика клика:

      for (let el of strLi) {
          el.addEventListener('click',func);
      };

      Во-первых - зачем каждый раз добавлять всем? Хорошо, что хоть объявление func вынесено за пределы текущей функции, иначе бы при каждом клике всем существующим li добавлялся новый обработчик.

      Во-вторых - пока не кликните по li, на свежесозданных li клик обрабатываться не будет (касается и тех, что изначально существуют).

      В-третьих - а на хрена оно надо? Вы же уже обрабатываете клик по li - так зачем назначать отдельный обработчик клика? То, что делаете в func, вполне можно делать прямо тут.


    А вообще, исправлять существующий код я бы не стал. Лучше его вырезать полностью и написать другой, получится гораздо проще и короче:

    document.querySelector('ul').addEventListener('click', e => {
      const t = e.target;
      const ct = e.currentTarget;
      t.insertAdjacentHTML('beforeend', ct === t ? '<li>text</li>' : '!');
    });
    Ответ написан
    Комментировать
  • JS Promise Memoize как правильно описать функцию?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function memoize(f, timeout) {
      const memo = {};
    
      return () => (new Date() < memo.time + timeout)
        ? Promise.resolve(memo.result)
        : f().then(r => (memo.time = +new Date(), memo.result = r));
    }
    Ответ написан
    Комментировать
  • Как отсортировать DOM элементы в обратную сторону на чистом js?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где надо развернуть элементы: const parent = document.querySelector('ul');.

    Разворачиваем:

    parent.querySelectorAll(':scope > *').forEach(n => parent.prepend(n));
    
    // или
    
    Element.prototype.append.apply(parent, [...parent.children].reverse());
    
    // или
    
    const [ first, ...rest ] = parent.children;
    first?.before(...rest.reverse());
    
    // или
    
    for (const n of parent.children) {
      parent.insertBefore(n, parent.firstElementChild);
    }
    
    // или
    
    for (let i = parent.children.length; i--;) {
      parent.insertAdjacentElement('beforeend', parent.children[i]);
    }
    
    // или
    
    const elems = Array.from(parent.children);
    while (elems.length) {
      parent.appendChild(elems.pop());
    }
    Ответ написан
    7 комментариев
  • Как определить первые цифры чисел массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const first = '125';
    const startWithFirst = arr.filter(n => first.includes(`${n}`[0]));
    
    console.log(startWithFirst);

    или

    const first = [ 1, 2, 5 ];
    const startWithFirst = arr.filter(n => first.includes(n / (10 ** (Math.log10(n) | 0)) | 0));

    или

    const first = /^[125]/;
    const startWithFirst = arr.filter(n => first.test(n));
    Ответ написан
    Комментировать
  • Как ограничить выход элемента за другой?

    0xD34F
    @0xD34F Куратор тега JavaScript
    новая_координата = Math.max(
      минимальное_допустимое_значение,
      Math.min(
        максимальное_допустимое_значение,
        текущая_координата + изменение_координаты
      )
    );

    https://jsfiddle.net/03mh1q78/
    Ответ написан
    Комментировать
  • Регулярное выражение для замены img на picture?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.querySelectorAll('img').forEach(n => {
      const src = n.getAttribute('src');
      if (!/^https?:\/\//.test(src)) {
        const picture = document.createElement('picture');
        picture.innerHTML = `<source srcset="${src}" type="image/svg+xml">${n.outerHTML}`;
        n.parentElement.replaceChild(picture, n);
      }
    });
    Ответ написан
  • Как сделать циклическую смену 3х цветов фона div при наведении и отведении мыши?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const el = document.querySelector('#box');
    const colors = [ 'red', 'green', 'blue' ];
    let index = -1;
    
    el.addEventListener('mouseenter', function() {
      index = (index + 1) % colors.length;
      this.style.backgroundColor = colors[index];
    });
    el.addEventListener('mouseleave', function() {
      this.style.backgroundColor = '';
    });
    Ответ написан
    Комментировать
  • Как ограничить количество одновременных запросов на сервер?

    0xD34F
    @0xD34F Куратор тега JavaScript
    подскажите, что мне нужно подправить

    Всё нужно подправить. А ещё больше - сделать.

    Ваша функция никак не извещает вызывающий код о том, что запросы выполнены и с какими результатами; результаты запросов - вместо того, чтобы сохранять все, сохраняете только последний полученный; вместо того, чтобы ограничить количество одновременно выполняемых запросов вы пропускаете один (кажется, вы просто не понимаете, как работает forEach).

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

    Под хранение результатов запросов создадим массив.

    Так как url'ы могут повторяться, а запросы не должны, выполним группировку массива url'ов в объект: ключи - url'ы, значения - массивы индексов, под которыми данный url встречается в исходном массиве. Выдернем из этого объекта ключи - это будет массив уникальных url'ов.

    Также создадим два счётчика - количество отправленных запросов и количество полученных ответов.

    Собственно запрос. Первым делом проверяем, сколько ответов получено - если все, резолвим промис массивом результатов. В противном случае проверяем, сколько запросов отправлено - если не все, увеличиваем соответствующий счётчик, отправляем запрос; по получении ответа достаём массив индексов url'а, сохраняем результат, увеличиваем счётчик полученных ответов и пытаемся отправить следующий запрос.

    Ну и запускаем всё это дело в работу - обычный цикл for, в котором на каждой итерации выполняется запрос. Минимум одна итерация (это на тот случай, если массив url'ов пустой), максимум - количество уникальных url'ов или ограничение на количество одновременных запросов, меньшее из этих значений.

    Всё:

    function makeRequests(urls, max) {
      return new Promise(resolve => {
        const results = Array(urls.length).fill(null);
        const groupedUrls = urls.reduce((acc, n, i) => ((acc[n] ??= []).push(i), acc), {});
        const uniqueUrls = Object.keys(groupedUrls);
        let countRequests = 0;
        let countResponses = 0;
    
        for (let i = 0; i < Math.max(1, Math.min(max, uniqueUrls.length)); i++) {
          request();
        }
    
        function request() {
          if (countResponses === uniqueUrls.length) {
            resolve(results);
          } else if (countRequests < uniqueUrls.length) {
            const url = uniqueUrls[countRequests++];
            fetch(url)
              .then(result => result.json())
              .catch(error => error)
              .then(result => {
                groupedUrls[url].forEach(n => results[n] = result);
                countResponses++;
                request();
              });
          }
        }
      });
    }

    Ответ написан
    Комментировать
  • Почему данный код работает не правильно?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Причина номер раз: потому что автор кода говнокодер. Ну, то есть - вы даже отформатировать код не удосужились. Причина номер два: проверяется состояние только одного инпута, того, где случилось событие. А надо проверять все.

    Исправляем:

    $('form').on('input', function() {
      $('.button').prop('disabled', $('input', this).get().some(n => !n.value));
    }).trigger('input');
    
    // или
    
    const form = document.querySelector('form');
    const button = document.querySelector('.button');
    const inputs = [...form.querySelectorAll('input')];
    form.addEventListener('input', () => button.disabled = !inputs.every(n => n.value));
    form.dispatchEvent(new Event('input'));
    Ответ написан
    5 комментариев
  • Как получать случайные уникальные числа из заданного интервала?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Создать массив, выдёргивать случайный элемент:

    function makeRandomizer([ min, max ]) {
      const numbers = [...Array(max - min + 1).keys()];
    
      return () => numbers.length
        ? min + numbers.splice(Math.random() * numbers.length | 0, 1)[0]
        : null;
    }

    Создать массив, перемешать его, доставать последний элемент:

    function makeRandomizer([ min, max ]) {
      const numbers = Array.from({ length: max - min + 1 }, (n, i) => min + i);
    
      for (let i = numbers.length; --i > 0;) {
        const j = Math.random() * (i + 1) | 0;
        [ numbers[i], numbers[j] ] = [ numbers[j], numbers[i] ];
      }
    
      return () => numbers.pop() ?? null;
    }
    Ответ написан
    5 комментариев
  • Как определить selected option?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('#sel1').change(function() {
      const min = +$(this).val();
    
      $('#sel2')
        .val((i, v) => Math.max(v, min))
        .children()
        .show()
        .filter((i, n) => +n.value < min)
        .hide();
    }).change();

    или

    const select1 = document.querySelector('#sel1');
    const select2 = document.querySelector('#sel2');
    
    select1.addEventListener('change', e => {
      const min = +e.target.value;
      select2.value = Math.max(select2.value, min);
      for (const n of select2.children) {
        n.hidden = +n.value < min;
      }
    });
    
    select1.dispatchEvent(new Event('change'));
    Ответ написан