Ответы пользователя по тегу JavaScript
  • Ошибка с библиотекой Route. В чем ошибка?

    @Flying
    Вы забыли импортировать компонент Routes, должно быть как-то так:
    import {Routes, Route} from 'react-router-dom';
    Ответ написан
  • Как подключить сторонние библиотеки сразу в scss, js файлы, если используешь gulp?

    @Flying
    Gulp - это не bundler, а task runner. Он просто запускает задачи и занимается их оркестрацией, что делают эти задачи - его вообще никак не касается.

    Используйте Gulp плагин для интеграции с нужным вам bundler'ом, к примеру webpack-stream.
    Ответ написан
    Комментировать
  • Почему не работает Gulp?

    @Flying
    У вас не установлен или не подключен gulp-sass.

    Более точно можно сказать только видя содержимое Gulpfile.js

    UPD: Причина наверняка в том, что версия gulp-sass ниже 5-й, поскольку синтаксис явного подключения компилятора появился только в 5-й версии. Нужно смотреть в package.json.
    Ответ написан
  • Почему в firefox возвращает json вместо страницы?

    @Flying
    Это происходит из-за неправильной организации работы с HTTP.

    Вы запрашиваете данные через XMLHttpRequest методом GET и по тому же url, что и сама страница. В результате получается, что у вас один и тот же HTTP метод и один и тот url отдают два разных ответа в зависимости от... непойми чего (видимо проверяется заголовок X-Requested-With), но это явно не то, что описано в спецификации HTTP.

    Ключевым моментом, естественно, является то, что запрос идёт методом GET. Если вы читали спецификацию HTTP или хотя бы статьи о протоколе HTTP, то должны помнить, что метод GET является идемпотентным. Из этого следует что клиент (в данном случае - браузер), имеет полное право (если разрешают условия кэширования) ожидать, что он получит тот же ответ на этот запрос и может оптимизировать это, использовав уже имеющийся в кэше результат. Именно это и происходит.

    Убедиться в том, что это так, можно очень просто: достаточно открыть dev.tools и на вкладке Network включить опцию "Disable cache". После этого вы увидите что проблема исчезла.

    Правильным решением будет выделение API для XHR запросов фильтра в отдельный endpoint. Также логичнее будет использовать метод POST, а не GET.

    Если же не хочется переделывать - хотя бы добавьте к XHR запросам ещё один query параметр, например xhr=1 и убедитесь что он никогда не появляется в url страниц. Это сделает ваши url для страниц и XHR запросов разными и уберёт проблему.

    Также имеет смысл пересмотреть объём данных, передаваемых в ответ на каждый запрос, ведь вам нужны только значения, передавать постоянно почти 100кб текста описаний нет особого смысла, они у вас и так уже есть.
    Ответ написан
    4 комментария
  • Как задействовать CSS в зависимости от значения scrollTop (pageYOffset)?

    @Flying
    Подобная функциональность - идеальный кейс для использования IntersectionObserver. Добавляете observer на элементы, соответствующие вашим экранам, определяете пороговое значение срабатывания - и дальше просто реагируете на события переходов между состояниями.

    Конечно возможны нюансы с тем что, к примеру, несколько (больше двух) ваших страниц попадут во viewport (помним что мониторы можно развернуть и вертикально, получив высоту viewport'а в 2k пикселей), но в целом получается весьма стабильно работающая схема.

    Дополнительный плюс в том что вам не нужно заниматься отслеживанием события scroll т.к. это и сложнее в реализации и менее надёжно и есть связанные с ним проблемы (подробнее в документации)
    Ответ написан
  • Как сделать бесконечный скрол без потери позиции?

    @Flying
    В первую очередь отказываться от любых переходов по страницам и реализовывать все как single page application. Всю навигацию делать самостоятельно используя history api. После этого появится много вопросов о том как оптимизировать работу с DOM и памятью, их придётся решать, а также появятся ещё более сложные вопросы о responsive поведении - их тоже придётся решать.

    У instagram интересное решение, но оно сильно специфично и, думаю, подходит только для их контента.
    Ответ написан
    2 комментария
  • Зачем нужен then в промисах если есть await?

    @Flying
    Отвечая на вопрос в заголовке: Async functions (тот самый async/await) появился в спецификации ECMAScript только в версии ES2017, Promise же появился сильно раньше.

    Отвечая на вопрос в тексте: then() вызывается в момент когда Executor (функция, переданная в Promise) вызывает переданный ей callback для resolve'а. Вообще это как-бы самая база использования Promise, так что возможно вам стоит освежить свои знания чтением документации.
    Ответ написан
    Комментировать
  • Где можно взять CSS стили для prompt Mozilla Firefox?

    @Flying
    Все стили для интерфейса Firefox можно найти в их репозитории, но надо понимать что кода там очень много.

    Также не стоит забывать что скорее всего внешний вид этого окна различается в зависимости от платформы, то что вы приводите - это внешний вид для Windows, но Firefox - кросс-платформенное приложение. Не забывайте также о наличии различных цветовых тем под которые подстраивается UI браузера. В общем задача сложнее чем вам, возможно, кажется.

    Существует такая вещь как system colors, смотрите в их сторону в качестве источника информации о цветах.
    Ответ написан
    Комментировать
  • SyntaxError: Cannot use import statement outside a module?

    @Flying
    Для того чтобы использовать ECMAScript Modules в Node.js вам необходимо выполнить любое из условий, включающее поддержку этих модулей. Условия описаны в соответствующем разделе документации.

    В целом всё выглядит довольно запутанным, но это следствие необходимости сохранения обратной совместимости.
    Ответ написан
    Комментировать
  • Как остановить местное время и запустить время по координатам?

    @Flying
    Ошибка довольно очевидна, хотя и размазана по коду. Однако причина её появления - в том что вы плохо понимаете те механизмы которые пытаетесь использовать. Другими словами это ошибка не техническая, а ошибка от недостатка знаний.

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

    Кроме того await date тоже по факту работает не совсем так как вы (скорее всего) ожидаете. Из MDN: "If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise." Таким образом const currDate = await date в вашем случае эквивалентно const currDate = date.

    Далее, следите за руками:

    Сначала вы передаёте в setInterval функцию без дополнительных аргументов. Она работает по причинам, описанным выше.

    Затем вы передаёте в setInterval() значение вызова setSearchTime() третьим аргументом (т.е. аргументом для интервальной функции). При этом, как вы сами пишете - функция setSearchTime() у вас возвращает Promise что по определению - обещание вернуть одно значение.

    Таким образом когда вы передаёте этот третий аргумент - ваша функция начинает получает значение аргумента date (т.е. перестаёт отрабатывать генерация значения по-умолчанию). При первом вызове ваш Promise, переданный в качестве аргумента в интервальную функцию, переходит в состояние fulfilled и отдаёт значение, но дальше этого уже не будет происходить т.к. Promise уже в состоянии fulfilled, так что вы будете всегда получать одно и то же значение. Однако это будет происходить не потому что setInterval не работает, а потому что вы и передаёте одно значение.

    Если вы (сами или из описания выше) понимаете как всё это работает на самом деле - то решение проблемы становится очевидным: вам всего лишь нужно передавать в вашу функцию setCurrTime не значение времени, а функцию-генератор времени. Тогда её вызов на каждой итерации будет приводить к созданию нового значения времени и всё начнёт работать.

    Также пара замечаний которые не относятся непосредственно к вашему вопросу, но являются важными:
    1. Ваша функция отображает время с точностью до минуты, но вызывается каждые 100 миллисекунд. Таким образом она 600 раз генерирует одно и то же значение что, очевидно, неразумно
    2. Сама функция преобразования времени у вас не показана, но важно чтобы эта функция не опиралась на setInterval в качестве источника информации о количестве прошедшего времени. Вместо этого вы должны всегда отталкиваться от new Date() и модифицировать этот объект. В качестве примера почему так попробуйте себе представить что компьютер с браузером в котором запущен ваш скрипт, был отправлен в гибернацию на какое-то время, а потом вернулся назад
    Ответ написан
    8 комментариев
  • Как вам такое решение задачки?

    @Flying
    Можно воспользоваться тем фактом что в JavaScript в reduce()передаётся текущий индекс и сам массив, это позволяет упростить backreference. В итоге у меня получилось нечто подобное:
    /**
     * @param {Array} list
     * @return {string}
     */
    const range = list => list
        .sort((a,b) => a - b)
        .reduce((r, v, i, a) => {
            if (i > 0 &&  v - a[i - 1] === 1) {
                let l = r.pop();
                l.push(v);
                r.push(l);
            } else {
                r.push([v]);
            }
            return r;
        }, [])
        .map(v => v.length > 1 ? `${v.shift()}-${v.pop()}` : v)
        .join(', ');

    Кусок с pop/push можно ускорить за счёт усложнения обращения к массивам, но так код получается выразительнее.

    Отдельное спасибо Дмитрий за .sort((a,b) => a - b) - не знал
    Ответ написан
  • Как скорректировать отображение событий в Firefox инспекторе DOM?

    @Flying
    Эта конструкция специфична для jQuery и по сути означает что реальный обработчик вешается на body, но в нём есть дополнительная проверка Event.target на совпадение с указанным селектором.

    Таким образом браузер не знает (и не может знать) о подобном поведении, поэтому показывает только имеющийся реальный обработчик.
    Ответ написан
  • Gulp 4 выдает в «The following tasks did not complete... Did you forget to signal async completion». Как это исправить?

    @Flying
    У вас вызов cb() стоит после return т.е. он вообще не вызывается. Но поскольку в списке аргументов он есть - gulp ожидает его вызова и, не дождавшись, ругается.

    В вашем случае cb вообще не нужен, просто уберите его из списка аргументов и всё начнёт работать.
    Ответ написан
  • Почему regEx не работает в firefox?

    @Flying
    regex101 тоже не может разобрать вашу регулярку, так что видимо вопрос в синтаксисе. Да и парсить адрес регуляркой - так себе идея, что вы будете делать если последовательность элементов в адресе будет другой или если там будут опечатки?

    Возможно вам стоит рассмотреть использование внешних сервисов которые нормализуют адреса? К примеру я в одном проекте использовал DaData и они действительно хорошо работают (не реклама :) ).
    Ответ написан
    4 комментария
  • Как сделать такой Range slider?

    @Flying
    Посмотрите на noUiSlider, он (как следует из названия) весьма хорошо кастомизируется, обладает богатым функционалом и не имеет ненужных зависимостей.
    Ответ написан
    Комментировать
  • Красивый lightbox для фото и видео?

    @Flying
    Если использование jQuery разрешено - могу рекомендовать Magnific Popup
    Ответ написан
    Комментировать
  • Import в nodejs 10.11.0 - как заставить работать?

    @Flying
    Как указано в документации - ES6 imports работают только в файлах с расширением .mjs при включенном флаге --experimental-modules

    О причинах такого поведения хорошо написано в статье от одного из разработчиков node.js
    Ответ написан
    Комментировать
  • У примитивных значений тоже есть методы?

    @Flying
    В JavaScript есть 6 примитивных типов данных, не имеющих методов: boolean, null, undefined, Number, String, Symbol. Тем не менее для примитивного типа String разрешается вызов методов объекта String, в этом случае просто создаётся временный объект String со значением примитивного типа.

    Вообще рекомендую JavaScript Guide на MDN, там много интересного.
    Ответ написан
    Комментировать
  • Как сделать индикатор загрузки?

    @Flying
    Используйте Promise.all для двух промисов:
    • В первом будет загрузка (jQuery.ajax() возвращает jqXHR в котором есть метод always, в нём и будете вызывать resolve())
    • Во втором будет setTimeout() с убиранием надписи и вызовом resolve() с нужной вам задержкой
    Ответ написан
    Комментировать