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

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    A. Использовать css animation.
    B. Использовать для программной анимации requestAnimationFrame вместо setInterval.
    B.1. Не тасовать элементы в dom.

    A&B. Использовать для анимации transform: translate вместо position.
    Ответ написан
    2 комментария
  • Как записать голосовое сообщение?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    На второй вопрос вам ответил Stalker_RED, ответ же на первый вопрос:
    потому что, даже после того как вы остановили MediaRecorder, сам аудио-поток(stream) у вас всё ещё захвачен и вы можете слушать его дальше.
    Чтобы остановить поток - надо остановить все трэки в нём, примерно так:
    function stopStream(stream) {
      stream.getTracks().forEach(
        (track) => track.readyState === 'live' && track.stop()
      );
    }


    P.S. К Vue вопрос отношения не имеет.
    Ответ написан
    Комментировать
  • Почему возникает ошибка Cannot read properties of null (reading 'hasOwnProperty')?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Ошибка точно не в этой строке, а в каком-то магическом коде.

    Почему оно возникает?
    С высокой вероятностью можно предположить, что:
    1. window.dataLayer уже существует.
    2. window.dataLayer.push переопределён или window.dataLayer является реактивным (vue?) массивом и отслеживает добавления.(что суть одно)
    3. При push вызывается некая функция, которая без всяких проверок на то что значение не пустое делает условно так: puhedValue.ecommerce.hasOwnProperty(...) на чём благополучно и падает.

    Что делать?
    Не добавлять объект, в котором ecommerce: null, эта хрень ожидает, что ecommerce будет объектом и никак иначе.

    Почему?
    Хз, читайте доки, наверняка там описано как делать надо и не надо(ну или наоборот НЕ описано подобного варианта с null, что тоже вариант).
    Ответ написан
  • Может ли браузерный javascript обработать post запрос?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    В комментах мы нашли решение настоящей проблемы автора вопроса, однако для тех кто будет искать после, как заметил там же Lynn «Кофеман», таки есть одно решение которое будет работать, ServiceWorker с примерно таким кодом:
    self.addEventListener('fetch', (event) => {
      const path = event.request.url.replace(location.origin, '');
      
      if (event.request.method === 'POST' && path === '/byFile') {
        return event.respondWith(
          event.request.formData().then(async (data) => {
            const file = data.get('image');
            
            let resonse = { success: false };
            
            if (file) {
              // await api call
              const { name, size } = file;
              resonse = { success: true, name, size };
            }
            
            return new Response(JSON.stringify(resonse));
          })
        );
      }
    });

    Он позволит перехватывать все POST запросы к url /byFile и таки делать с этими запросами что хочешь.

    Но, конечно, так делать ни в коем случае не стоит. Скорее всего ваша задача, как и у автора поста, имеет простое и элегантное решение, не требующее подобных извращений.
    Ответ написан
    Комментировать
  • Как распределить элементы (объекты) массива в ОБЪЕКТ с объектами (не сортированными) по убывающей сумме данных из объектов ОБЪЕКТА?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Задача не очень понятна если честно. Так чтоли?
    const sum = ({data}) => data.reduce((a, b) => a + b, 0);
    
    const colors = [
      { primary: '#AAAAAA', secondary: '#AAABBB' },
      { primary: '#BBBBBB', secondary: '#BBBCCC' },
      { primary: '#CCCCCC', secondary: '#CCCDDD' },
      { primary: '#DDDDDD', secondary: '#DDDEEE' },
    ]; // ЦВЕТА ВСЕГДА В НУЖНОМ ПОРЯДКЕ
    
    const DATASETS = [
      {
        data: [1, 2, 3, 4, 5],
      },
      {
        data: [2, 3, 4, 5, 6],
      },
      {
        data: [3, 4, 5, 6, 7],
      },
    ]; // МАССИВ МОЖЕТ БЫТЬ ОГРОМНЫМ, ДАННЫЕ ТОЖЕ
    
    const NEW_DATASETS = DATASETS
      .map((dataset, index) => [sum(dataset), index]) // получаем соответствие суммы индексу
      .sort(([a],[b]) => b - a) // сортируем по сумме в обратном порядке
      .map(([,sortedIndex], index) => ({
        ...DATASETS[index],
        ...colors[sortedIndex]
      }));


    Х.з. зачем такое может понадобится, если честно.
    Ответ написан
  • Можно ли переопределить свойство Location в браузере?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Нет.

    Переписать что-то у себя ты может и сможешь, но безопасность и ограничения фрейма опираются на браузер, а не на изменённый код.
    Ответ написан
    Комментировать
  • Почему vs code выдаёт такое?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    В любой непонятной ситуации тыкаешь ctrl+click и читаешь, что там написано.

    В данном случае это ложное срабатывание на попытку переписать window.name. Можешь им баг запилить.
    Еслиб ты сделал так var { name, surname, age } = myUser, то это было бы реальной ошибкой: ты неявно бы менял name окна, но для const это не актуально.

    Ну и, по-хорошему, не стоит заводить переменные в глобальной области. Если ты используешь js-модули или хотя-бы завернёшь свой код в блок или функцию - такой проблемы не возникнет.
    Ответ написан
    1 комментарий
  • Как заполнить форму на сайте через JS?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Вот тебе универсальная функция:
    function setValue(element, value, options) {
      if(typeof element === 'string') 
        element = document.querySelector(element);
    
      options = Object.assign({
        bubbles: true
      }, options);
    
      element.dispatchEvent(new MouseEvent('mousedown', options));
      element.dispatchEvent(new MouseEvent('mouseup', options));
      element.dispatchEvent(new MouseEvent('click', options));
      element.dispatchEvent(new Event('focus', options));
      element.dispatchEvent(new Event('keydown', options));
      element.dispatchEvent(new Event('keypress', options));
    
      element.value = value;
    
      element.dispatchEvent(new Event('input', options));
      element.dispatchEvent(new Event('keyup', options));
      element.dispatchEvent(new Event('change', options));
    
      setTimeout(() => element.dispatchEvent(new Event('blur', options)));
    
      return element;
    }
    
    setValue('input[name="email"]', 'новое_значение@example.com')


    Половина событий в данном случае может быть лишней, но может где-то ещё пригодиться.
    Ответ написан
  • Зачем нужен третий параметр array для обратной функции в forEach, map, filter...?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Чтоб можно было использовать функции из других модулей\библиотек, у которых нет доступа к текущему массиву напрямую из области видимости.

    Для чего может понадобится весь массив? Да для много чего. Например классический(но не оптимальный) фильтр уникальных значений:
    const uniq = (value, index, array) => !array.includes(value, index + 1);
    
    [1, 2, 2, 3, 3, 3].filter(uniq) // [1, 2, 3]
    Ответ написан
    Комментировать
  • Как в JSDoc описать тип через результат вызова функции?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Зависит от того, что вам нужно: "шашечки или ехать".

    Коли первое - то тут уж надо глубоко изучать документацию по jsdoc, без гарантированного результата. Ради (почти) никому не нужных извращений я не возьмусь. :)

    Коли второе - IDE сейчас кушают любой typescript в jsdoc, потому просто смело пихаете:
    /** @type {Array<ReturnType<typeof createElement>>} */
    и оно заработает. Но никаких долговременных гарантий.
    Ответ написан
    1 комментарий
  • Как исправить ошибку eslint на события мыши?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Чтобы исправить эту и многие иные ошибки надо включить мозг. Прям остановиться, нажать кнопку power on, и таки прочитать: кто тебе пишет, что тебе пишет, почему он тебе такое пишет.

    Итак:
    Кто тебе пишет? Пишет тебе набор правил vuejs-accessibility(vuejs-доступность по нашему). Этот набор правил сам по себе появиться не мог, он ставится дополнительным плагином. Если ты не знаешь откуда он у тебя взялся и тебе плевать на всяких инвалидов - можешь смело удалить этот плагин из eslint и забыть.

    Что тебе пишет? Коли по-басурмански ты не разумеешь, то тебе поможет гугл-транслейт:
    1. @mouseout или @mouseleave должны сопровождаться @focusout или @blur для доступности.
    2. @mouseover, @mouseenter или @hover должны сопровождаться @focusin или @focus для доступности.

    Почему он тебе такое пишет? Вот тут запускай свой мозг на все 146% и начинай по-нстоящему думать. Почему же совместно с @mouseenter нам может понадобится @focusin, если нам это советует правило по доступности? Думай, думай...
    Может быть для того, чтобы человек без возможности оперировать мышью смог таки с помощью клавиатуры вызвать связанные события, мм? И небольшое дублирование кода, которое поможет таким людям, совсем не страшно.

    P.S. Пока не выключен мозг - подумай ещё:
    1. К каким последствиям приведёт бездумное (лишь-бы-eslint-заткнулся) добавление одновременно @focus и @focusin?
    2. Не будет ли конфликтов внутри функций в случае получения элементом фокуса таки мышкой?
    ...
    Ответ написан
    Комментировать
  • Как решить проблему с сохранением выбранного языка при смене языка на мобильных устройствах?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Вопрос в том что ты там закрываешь и открывешь, что у тебя в {{Route('ChangeLanguage', N)}}?
    Если там что-то вида /en и /tr то у тебя будет открываться собственно та версия, которая сохранена в закладках\истории, а не так которая была выбрана.

    Почему? Потому что твой код не предусматривает автоматическую смену адреса при загрузке, только при выборе.
    Если ты ожидал, что
    selectLang.selectedIndex = localStorage.getItem(storageKey);
    вызовет change автоматически - это не так, программная смена не вызывает событий.

    Теперь о самом коде:
    1. Нахрена там fetch? Ты зачем-то грузишь страницу в воздух, после чего переключаешь на неё.
    2. Весь код в принципе хрень. Перенаправление на нужный язык должно происходить на сервере. Если нужен выбор на клиенте с запоминанием - используй куки и читай эти куки на сервере.
    Ответ написан
    6 комментариев
  • Как убрать окошко, которое появляется на мобильном устройстве при долгом касании на ссылку?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Да вроде работает:
    В каком именно браузере проблема?
    Ответ написан
    Комментировать
  • Как решить проблему с кодировкой при чтении Excel файла?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Измени:
    const htmlStr = xlsx.write(wb, { type: "binary"
    на:
    const htmlStr = xlsx.write(wb, { type: "string"

    "binary" - это спецформат т.н. "бинарная стока", она подходит для записи в файл напрямую побайтово, но не подходит для отображения на экране.
    Ответ написан
    Комментировать
  • Как исправить ошибку "Property *** does not exists on type ''IntrinsicAttributes" в React+TypeScript?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Тебе английским по белому написано: "Property todos does not exists", что тут непонятно?

    Твой компонент TodoList не ожидает пропа todos.
    Ответ написан
    Комментировать
  • Как лучше сделать авторизацию в NUXT?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Про "очень просто" ты меня сейчас сильно насмешил. Тот же OAuth - это просто адище под капотом. Но даже в basic auth есть куча мелочей на которых можно запороться.
    В общем использовать само собой следует либу, сам ты гарантировано словишь тонну багов и дыр в безопасности, только выбирать более-менее приличную(на глазок - больше 1000 Weekly Downloads на npmjs.com и от не вызывающего подозрений автора).

    Со стороны nuxt очевидно лучше всего подойдёт https://auth.nuxtjs.org/ , со стороны laravel - хз, гугли реализацию одного из вариантов поддерживаемых auth.nuxtjs.

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

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Верить клиенту конечно нельзя, но можно сделать вид что веришь:
    1. рассчитывай число и на клиенте и на сервере.
    2. в начале расчёта один раз синхронизируй с сервером.
    3. выводи рассчитываемое на клиенте число с какой угодно плавностью.
    4. если синхронизация прям очень важна - продолжай слать число с сервера и сравнивать с клиентом, если разница в пределах (заданной) погрешности - ничего не делай, еслы вышла за пределы - меняй клиентское(ничего страшного если такое будет происходить изредка).
    5. если сама по себе синхронизация не особо важна, а важно лишь конечно число, то собственно сравнивай клиентское с серверным только в самом конце. Если совпало (с погрешностью в нужную сторону) - всё ок. Не совпало - клиент хацкер - идёт нафиг.

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

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Потому что селектор div.filtr form ul li:not(.sf-field-sort_order) выбирает все li(кроме .sf-field-sort_order) которые находятся внутри div.filtr form ul, т.е. и <li>тест</li> в том числе. Если тебе нужны только прямые потомки, то надо писать так:
    div.filtr > form > ul > li:not(.sf-field-sort_order)
    и тогда всё будет работать как ты задумывал.
    Ответ написан
    Комментировать
  • Как выполнить запрос н-раз?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
    
    const request = () => fetch('https://your-request-url.ru')
    	.then(response => response.json())
      .then(console.log);
    
    async function repeat(request, interval = 5000, times = Infinity) {
      do {
        await request();
        
        if (--times < 1) break;
        
        await delay(interval);
        
      } while (true);
    }
    
    repeat(request, 5000, 5)
    Ответ написан
    Комментировать
  • Как оставить цвет текста при переключении языка на сайте?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Сделать октоторп элементом стиля, а не частью слова:
    .nav-link::before {
        content: '#';
        font-weight: bold;
        color: #f0f;
    }
    Ответ написан
    1 комментарий