Ответы пользователя по тегу JavaScript
  • Насколько сложна эта задача?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если дочитали документацию JavaScript до Set, то решение совсем простое: перевести массив в сет (останутся только уникальные значения), и сет обратно в массив.

    upd. неправильно понял задачу. Если надо вернуть только элементы, которых в исходном массиве ровно 1 штука, то надо видимо считать. Сделать объект, где ключи строки, значения число, сколько раз нашлись. { "кришна": 4, "харе": 4, ":-O": 1 }Оставить только те, где значения 1. Собрать в массив.

    Или оставить те, что с начала и с конца находятся только «здесь и сейчас»:
    const unique = arr => arr.filter((item, i) => i === arr.indexOf(item) && i === arr.lastIndexOf(item));
    Ответ написан
    Комментировать
  • Как каждый раз отправлять новый элемент массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    заведите переменную счётчик:
    let offset = 0;
    async function requestAndTreatment() {
      // ...
      const point = res.data[offset++];
      data.addData([[res.timestamp, point.open, point.high, point.low, point.close]]); 
    }

    вообще перепроверьте логику: мне кажется странным, что из данных API вы хотите с каждым разом брать следующую позицию. Как будто они одни и те же каждый раз. А как до конца дойдёте, что дальше?
    Ответ написан
  • Как сделать, чтобы работали все кнопки лайка?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    main.querySelectorAll('.element__button')
      .forEach(el => el.addEventListener('click', () => el.classList.add('element__button_active')));
    Ответ написан
    1 комментарий
  • Как обновить значение в object?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если задача иметь каждый раз «актуальные» секунды,
    наверное, стоит сделать геттер для свойства second,
    который каждый раз будет вычислять значение:
    const timerObject = {
      DATE: new Date(),
      listDATE: {
        get second() {
          return new Date().getSeconds();
        },
      },
    };
    
    // читать, как обычно
    console.log( timerObject.listDATE.second );
    
    // через секунду
    setTimeout(() => console.log( timerObject.listDATE.second ), 1000); // на 1 больше

    Сеттер вроде при этой задаче и не требуется. Просто хочется получать каждый раз актуальное значение?
    Ну или ещё проще, сделайте просто метод:
    const timerObject = {
      DATE: new Date(),
      listDATE: {
        second: () => new Date().getSeconds(),
      },
    };
    
    // использование
    console.log( timerObject.listDATE.second() );
    Ответ написан
    1 комментарий
  • В чём ошибка в задаче?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Три подсказки.

    Проверить, что аргумент является строкой:
    typeof arg === 'string'
    // ещё можно длину проверить, а то, вдруг длинное пришлют
    arg.length === 1

    Проверить, что это буква и есть пара в другом регистре:
    arg.toLowerCase() !== arg.toUpperCase()
    // строка перевелась в разные кейсы

    В каком кейсе изначально была буква:
    arg.toUpperCase() === arg // значит, буква в верхнем регистре


    Из этих кирпичиков остаётся сложить домик. И чтоб не рухнул )
    Ответ написан
    1 комментарий
  • Не понимаю, как это работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Просто прочитайте документацию или ещё что-то про сортировку.

    Вопрос «что здесь принимается за a, а что за b?» не самый удачный: в примере аргументы игнорируются.
    В этом странном коде возвращается всегда отрицательное число. Значит, результат сортировки массива зависит только от внутренней реализации — от того, в каком порядке будут сравниваться пары элементов.
    Ответ написан
  • Как JS проверить на пустоту или создание объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    элемент же может и отсутствовать?

    Тогда document.querySelector("#******") вернёт undefined, и попытка получить из него свойство innerText выкинет ошибку. Загляните в консоль.

    Наверное, нужно проверять два условия: чтобы и элемент нашёлся, и чтобы текст в нём оказался не пустой строкой.

    Что-то типа
    const el = document.querySelector("#******");
    if (el) {
      const a = el.innerText;
      if (a.length === 0) {
        el.value = "123"; // а что это за элемент, у которого и innerText и value ?
      }
    }
    Ответ написан
    Комментировать
  • Как отслеживать смену значений в объекте?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const obj = { name: 'Boris', age: 5};
    
    // переназначить свойство с геттерами и сеттерами
    // ниже очччень сокращённый пример
    Object.defineProperty(obj, "name", {
      set(newName) {
        console.log("Name changed to", newName);
      }
    });
    
    // проверяем:
    obj.name = "Toster"; // в консоль выведет "Name changed to Toster"
    на деле нужно сохранить начальное значение, где-то хранить значение свойства name, и добавить геттер. Т.к. вероятно, не единственное свойство захочется так подменить, лучше будет воспользоваться «оптовым» Object.defineProperties() или в цикле по свойствам объекта каждое сделать реактивным интерактивным.

    Подробнее см. примеры для Object.defineProperty()
    Ответ написан
    2 комментария
  • Почему не отрабатывает forEach?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Дело в том, у какого объекта вызывать метод forEach()

    Сейчас, очевидно, вызываете на массиве или статичном NodeList'е, в который свежедобавленный элемент не попадает.

    Почувствуйте разницу между статичным и динамическим NodeList'ом. Первый содержит только те элементы, которые в него попали на момент создания. Динамический будет содержать и добавленные после.

    querySelectorAll() возвращает статичный набор.

    Решение, в общем – либо заново собирать элементы, и по ним запускать forEach(), или же получать динамическую коллекцию, используя соотв. метод.
    Ответ написан
    Комментировать
  • В каком порядке выполняется этот код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. объявили функцию
    2. зарядили первый таймаут: он через 1 секунду вызовет showNumber(1)
    3. ... пауза 1c, ничего не происходит
    4. вызвалась showNumber(1) - вывела в консоль "1", и зарядила новый таймаут, уже с showNumber(2). Убедились, что 2 не равно 6.
    5. ... пауза 1с, опять скукота, ничего не происходит
    6. вызвалась showNumber(2), вывели в консоль "2", зарядили таймаут (3)
    7. ... ... ...
    8. наконец поднялся счётчик до 5. Всё то же: зарядили таймаут, прошла 1 секунда,
      вызвалась showNumber(5)
      Тоже выводит в консоль "5", заряжает таймаут (6), но на этот раз срабатывает условие 6 === 6, и раз так — тут же гасит свежезаряженный таймаут, ибо нечего ему срабатывать.
    9. Занавес.


    Наверное, не уловили пока, как работает setTimeout(). Вызов setTimeout() отрабатывает сразу и выполнение идёт дальше. Но этот вызов не выполняет, а лишь откладывает на потом – задачу вызова какой-то функции с параметрами.

    Пишет письмо с заданием, запечатывает в конверт и относит на почту. И идёт дальше по своим делам. А когда-то там письмо дойдёт, наконец – его распечатают и выполнят задание.
    Ответ написан
    Комментировать
  • Как найти координаты Б когда известны координаты А, C?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если даны только точки A, C — точку B можно располагать как угодно – они задают квадратичную кривую Безье втроём. Посмотрите примеры — ваш случай второй. Точки можно двигать.
    Ответ написан
    1 комментарий
  • Как проверить одинаковые данные?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Метод массива find() поможет найти, есть ли в массиве объект, удовлетворяющий требованию (вернёт этот объект или undefined)
    const users = [
      {name: 'Ann'},
      {name: 'George'},
      {name: 'Rebecca'}
    ];
    
    if (users.find(user => user.name === 'Rebecca')) {
      // уже есть такой юзер
    } else {
      // добавляем
    }
    Ответ написан
  • Почему setTimeout не работает в then?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пока путаете функцию – с результатом её выполнения.
    Смотрите, что передаётся первым аргументом в setTimeout():

    setTimeout(console.log(p), 6000);
    здесь передаётся результат вызова console.log()

    setTimeout(console.log, 6000, p);
    а вот тут передаётся функция console.log, которую setTimeout() вызовет с аргументом p через 6 секунд.
    Ответ написан
    Комментировать
  • Как оптимизировать код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно постараться не повторять себя (DRY = don't repeat yourself).
    const data = [];
    
    document.querySelectorAll('.item_row').forEach(row => {
      const region = row.querySelector('.item_region > a')?.textContent?.trim();
      if (region !== 'Минск') return;
    
      const name = row.querySelector('.title')?.textContent;
      const link = 'https://zooby.by/' + row.getAttribute('href');
    
      data.push({ name, link });
    });
    Ответ написан
    2 комментария
  • Как разрешить в input ввод только конкретных цифр?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Напомню, что input работает не с числами, а с текстом — строками.

    Может брать последний символ из строки? Если он 1..6 то заменять им всю строку (сделает из "12" просто "2"). Иначе ставить пустую строку:
    const input = document.querySelector('.input');
    
    input.addEventListener('input', event => {
        const { target } = event;
        const { value } = target;
        const last = value.slice(-1);
        target.value = last.match(/[1-6]/) ? last : '';
    });

    Вообще для такой задачи в интерфейсе может, вместо текстового поля лучше просто шесть кнопок сделать? От 1 до 6. Один тык — один выбор.
    А то с текстовым полем надо больше действий: перейти в него, нажать на клавиатуре цифру.
    Ответ написан
    Комментировать
  • Почему событие работает только на последнем элементе?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Цикл отработал, в переменной li содержится последний созданный элемент.
    На него и вешаете слушатель события, уже снаружи цикла.

    На все предыдущие элементы слушателя никто так и не повесил.

    Лучше как-то так:
    const clickHandle = () => {
      // ...
    };
    
    for (let i = 0; i < count; i++) {
      const li = createGameElement(newArr[i]);
      const { item } = li;
      ul.append(item);
      item.addEventListener('click', clickHandle);
    }
    Ответ написан
    Комментировать
  • Как анимировать объект по траектории?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вот пример для SVG: animateMotion и атрибуты path и rotate
    Ответ написан
    Комментировать
  • Как найти ближайшую дату в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    /**
     * My item definition
     * @typedef {Object} myItem
     * @property {string} date
     * @property {string} id
     */
    
    /**
     * Find item with the date of today 
     * or the nearest one in the future
     * @param {myItem[]} data 
     * @returns {?myItem}
     */
    const getNearest = data => {
      const now = new Date();
      const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    
      const index = data
        .map(({date}, orginalIndex) => {
          const [d, m, y] = date.split('/');
          return { sorter: new Date(y, m - 1, d), orginalIndex };
        })
        .sort((a, b) => a.sorter - b.sorter)
        .find(item => item.sorter >= today)
        ?.orginalIndex;
    
      return data[index] || null;
    }
    
    
    // использование
    const data = [
      { date: '01/01/2022', id: '1' },
      { date: '31/03/2022', id: '2' },
      { date: '23/05/2022', id: '3' },
      { date: '05/04/2022', id: '4' },
      { date: '03/04/2022', id: '5' },
      { date: '09/04/2022', id: '6' },
    ];
    
    getNearest(data) // { date: "03/04/2022", id: "5" }
    Ответ написан
  • Выражение внутри switch?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Строгое равенство === выражения в switch() с очередным case должно дать true, чтобы выполнился код в этом case.

    Поэтому ваш исходный код никогда не выполнит первый случай; 2-й выполнится только когда var = true а в остальных случаях будет срабатывать default. Наверное, не совсем то, что хотелось?
    Ответ написан
    Комментировать
  • Как писать асинхронный код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    тут можно через событие окончания transition — transitionend:

    function removePopUpFilter() {
      const filterContainer = document.querySelector('.filter-container');
      filterContainer.style.opacity = '0';
      filterContainer.addEventListener('transitionend', () => filterContainer.remove());
    };
    Ответ написан
    3 комментария