Ответы пользователя по тегу JavaScript
  • Как отсортировать массив в порядке другого массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const a = { x: 1, y: 2}; // главные свойства
    const b = { y: 3, z: 5}; // второй товар для сравнения с главным
    
    const comparison = {
      // каждому из свойств A подставляем значения из B или прочерк если нет
      ...Object.keys(a).reduce((acc, c) => (acc[c] = b[c] ?? '-', acc), {}),
      // дописываем поверх свойства B
      ...b
    }
    
    // получилось:
    { x: "-", y: 3, z: 5 }
    Ответ написан
  • Почему не работает апи вк?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. любые запросы к VK API должны иметь обязательные параметры – в т.ч. access_token.
    2. из браузера этот запрос не выполнится по причине CORS политики безопасности. Попробуйте из NodeJS
    Ответ написан
    Комментировать
  • Как узнать какой index у блока, на который нажал пользователь, если таких блоков много и могут добавляться?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно искать индекс кликнутого блока в коллекции дочерних элементов в свойстве Element.children родительского div'а:
    Ответ написан
    1 комментарий
  • Можно ли удалить все ключи в localstorage, начинающиеся с определенной буквы? И если да, то - как?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Похоже, вопрос вы изменили. Судя по ответам, сначала спрашивали про просто-объект. А затем про localStorage.
    for (let i = localStorage.length - 1; i >= 0; i--) {
      const key = localStorage.key(i);
      if (key.substring(0, 4) === 'Habr') {
        localStorage.removeItem(key);
      }
    }
    Ответ написан
    Комментировать
  • Почему тут TypeError у map?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    alert(camelize(str));
    надо же передать аргумент в функцию..

    и зачем тут .str в .str.join('') – уберите, оставьте только .join('')
    Ответ написан
    Комментировать
  • Как выполнить условие выбора двух select option?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Два селектора – один обработчик.
    Надо в одном обработчике смотреть на все значения всех селекторов.
    const colorSelect = document.querySelector('.hasCustomSelect[name="features[13]"]');
    const plugSelect = document.querySelector('.hasCustomSelect[name="features[12]"]');
    
    const onChange = () => {
      const colorValue = colorSelect.value;
      const plugValue = plugSelect.value;
    
      if (colorValue === '1' && plugValue === '42') {
        console.log('Оба, на', { colorValue, plugValue });
      } else {
        console.log('Всё не то..', { colorValue, plugValue });
      }
    };
    
    [colorSelect, plugSelect].forEach(el => el.addEventListener('input', onChange));
    Ответ написан
    1 комментарий
  • Как проверить есть ли в тексте выделение жирным?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно спарсить фрагмент HTML в документ, в котором обычными методами вроде querySelector() поискать нужный тег:
    const code = `
    <li class="search__list-item">
      <div class="search__img-wrap">
        <img class="search__img search__img_indents" src="search.svg" alt="Иконка">
      </div>
      <strong>поиск</strong>
      текста
    </li>
    `;
    
    const parser = new DOMParser();
    const doc = parser.parseFromString(code, 'text/html');
    
    if (doc.querySelector('strong')) {
      console.log('Есть!');
    }
    Ответ написан
    Комментировать
  • Как у объекта в sessionStorage получить проверку количества ключей?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Приз за самый оригинальный способ посчитать число букв в строке текста "[object Object]"

    storage умеет хранить только строки текста. Поэтому
    - sessionStorage.setItem('user', {level: '1'})
    + sessionStorage.setItem('user', JSON.stringify({level: '1'}));
    и
    - console.log(Object.keys(sessionStorage.getItem('user'))
    + console.log(Object.keys(JSON.parse(sessionStorage.getItem('user')))
    Ответ написан
    Комментировать
  • Как вызывать функцию с теми же аргументами не более одного раза?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    memoization
    это называется «мемоизация» (не от слова «мем», нет : ) Функция запоминает значения аргументов и результат выполнения. Если уже вызывалась с такими аргументами – вернёт «запомненное» значение, не выполняясь ещё раз. Статья на Хабре

    В качестве кэша можно использовать объект или WeakMap, если аргумент – объект.

    distributed lock
    Из вопроса не вполне понятно: в контексте одного выполнения скрипта только один раз, или глобально? Для глобального случая можно использовать какое-то быстрое хранилище, например, Redis, и механизм MutEx ("mutual exclusion" – взаимного исключения), например RedLock.

    На пальцах: вот есть аргумент X. То ли вызвать функцию, то ли параллельно уже другой процесс выполняет и скоро будет готовый результат — вопрос.

    Генерится случайный ключ. Пара (X, ключ) отправляется в асинхронное хранилище, где если нет ещё сохранённого значения под этот X, ячейка запирается (lock) этим ключом. Тут необходима особенность механизма самого хранилища – в Redis это "NX" – записывать только, если уже нет значения. Это гарантирует, при параллельных запросах, что только чьё-то одно случайное значение запишется. Закон джунглей: первый прибежал — наелся!

    Далее надо прочитать записанное значение и получить ключ. Сравнить со своим ранее сгенеренным ключом. Совпали? Значит, это именно мы заперли этот аргумент, и можно выполнить функцию. Не совпали – параллельный процесс выиграл. Просто запросим готовое значение чуть попозже.
    Ответ написан
    1 комментарий
  • Почему не передается event в функцию?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    sendButton.click(e => {
      setInterval(e => { ... }, 0, e); // третьим аргументом передать e
    }
    p.s. таймаут точно 0 ?
    Ответ написан
    Комментировать
  • Как вывести количество цифр в числе?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    для натуральных чисел можно так:
    Math.floor(Math.log10(123)) + 1 // 3
    десятичный логарифм числа, округлённый в большую сторону
    Ответ написан
    2 комментария
  • Как проверить передан ли в параметр функции event?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробовать так и сяк
    function func(mixedData) {
      const id = mixedData?.target?.id ?? mixedData;
      console.log(id);
    }
    
    func(123) // 123
    func({target: {id: 456}}) // 456

    Что это было?!
    ?.optional chaining
    ??Nullish coalescing operator

    Но это всё не фэн-шуёво, не аккуратненько как-то.
    Лучше бы функции строго принимать один тип параметра — ожидать только id.
    А что-то поменять при вызовах.
    Ответ написан
    6 комментариев
  • Как сделать отправку ajax каждые n секунд?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    function sendSomething() {
      // (отправляем запрос)
    
      // заряжаем паузу до следующей отправки
      setTimeout(sendSomething, 5000); // через 5 секунд повторить
    }
    
    sendSomething() // поехали!
    Ответ написан
    5 комментариев
  • Как понять это цикл while?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    result накапливает строку, и потом функция её возвращает.

    Сначала result — пустая строка: let result = '';

    В цикле, на каждой итерации, к этой строке в хвост приклеивается очередное число (как текст)
    // ""
     result = `${result}${i}`;
    // "1"
    
    // ...
    
    // "1"
     result = `${result}${i}`;
    // "12"
    
    // ...
    // "123"
    // "1234"
    // "12345"


    Ну и в конце эту строку возвращают return result; Поэтому если присвоить переменной результат выполнения этой функции, получится что-то типа:
    let digits = joinNumbersFromRange(0, 9); 
    // в переменной digits теперь "0123456789"
    Ответ написан
    3 комментария
  • Как значение сделать переменной?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var 42955707252979 = 12700; // так нельзя, синтаксическая ошибка
    имена переменных должны начинаться с не-цифры.

    Лучше создать объект:
    const data = {
      42955707252979: 12700,
    }
    
    // можно обращаться:
    data[42955707252979]  // 12700
    именами свойств объекта могут быть строки или Symbol'ы.
    Ответ написан
    Комментировать
  • Не закрывается div, если по нему кликнуть повторно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В обработчике клика сначала всем удаляется класс active,
    а только затем проверяется, по кому кликнули, и если убранного класса нет – он добавляется.

    Так при клике мгновенно удаляется-добавляется назад этот класс.

    Можно было бы удалять в начале не всем подряд, а всем, кроме себя.
    А для самого блока добавить вариант, что класс уже есть – тогда его убрать.

    Но вообще это некруто – полагаться на наличие/отсутствие классов. Лучше держать где-то данные — какой именно блок открыт. И в зависимости от этого отрисовывать интерфейс.

    Ответ написан
    2 комментария
  • Jquery клик по одному классу отдает одно и тоже?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const bk = $(this).text();
    Ответ написан
    Комментировать
  • Почему инициализация суммы в цикле while равна 1?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Функция умножает числа в цикле от start до finish.

    Так как это умножение, начальное значение не может быть 0, иначе результат всегда будет 0.

    По-хорошему, первым значением можно брать сразу первое число start и домножать, начиная со следующего start + 1:
    const multiplyNumbersInRange = (start, finish) => {
      let result = start;
      let i = start + 1;
    
      while (i <= finish) {
        result *= i;
        i += 1;
      }
      return result;
    };
    
    multiplyNumbersInRange(1, 3); // 1 * 2 * 3 = 6

    Надо определиться с крайними случаями: какой должен быть результат, когда в «умножении» участвует только одно число? (когда start === finish)
    Ответ написан
    1 комментарий
  • Как получить данные из функции(метода) после выполнения промиса?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Решите сначала упрощенную изолированную проблему (для себя)
    function getValue() {
      return new Promise(resolve => setTimeout(() => resolve(123), 2000))
        .then(data => data * 2);
    }
    Как вы получите значение 246 из этой функции «в переменную»?

    Когда разберётесь, скорее всего, разрешится и весь прочий «порочный круг асинхронности».
    Ответ написан
    Комментировать
  • Как связать кнопку с соответствующим объектом?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    можно, например, кнопки не писать в разметке, а создавать программно. Для кнопки нужны только название и имя картинки, а в остальном они одинаковы. Ну ещё активная кнопка получает 2 доп. CSS класса.

    Для отрисовки достаточно объекта типа
    spoiler
    const categories = {
      mass: 'Масса',
      distance: 'Расстояние',
      temperature: 'Температура',
      time: 'Время',
      speed: 'Скорость',
      currency: 'Валюта',
    };


    Там же, где создаются кнопки и вешается на них слушатель клика, можно их складывать в массив. И вот у вас массив элементов. Ещё каждой категории понадобятся данные с единицами измерения. Поэтому центральный объект данных можно примерно так представить:
    spoiler
    const categories = {
      mass: { title: 'Масса', element: null, data: null, },
      distance: { title: 'Расстояние', element: null, data: null, },
      temperature: { title: 'Температура', element: null, data: null, },
      time: { title: 'Время', element: null, data: null, },
      speed: { title: 'Скорость', element: null, data: null, },
      currency: { title: 'Валюта', element: null, data: null, },
    };
    В поле element пойдёт созданный HTML-элемент кнопки, а в поле data – что там сейчас в переменной mass у вас.

    Клик по объекту вешать сразу с этим же текущим объектом всех-данных:
    Object.entries(categories).forEach(([ name, item ]) => {
      const el = document.createElement('div'); // это внешний div кнопки
      // el.classList.add(...)
      el.insertAdjacentHTML('beforeend', `
        <p class="value-item__title">${item.title}</p>
          <img src="assets/img/values/${name}.svg" alt="" class="svg-icon value-item__img">
      `);
      el.addEventListener('click', () => clickHandler(name));
      // по этому name можно вытащить categories[name]
    
      divValues.appendChild(el);
    });
    Ответ написан
    1 комментарий