Ответы пользователя по тегу JavaScript
  • Безопасно ли использовать АПИ ключ гугла в исходниках?

    gscraft
    @gscraft
    Программист, философ
    Во-первых, Вы не скроете ничего, что передается с клиентской стороны, где бы оно ни хранилось. Такие ключи как правило публичны и не имеют риска хищения. Скажем, привязаны к домену, а для приватных операций требуют отдельной аутентификации/авторизации. Во-вторых, хранить какие-либо настройки в исходном коде в любом случае плохая идея. Все изменяемые значения должны быть вынесены в конфигурационный файл. Поскольку код должен быть распространяемым (отправляться в версии, применяться в других проектах, использоваться в иных условиях и т.д.). Если у Вас нет сборщика и не хотите усложнять кодовую базу, то как минимум в отдельный, подключаемый JS-файл.

    PS Еще один момент, если речь о ключе, который получается в результате аутентификации в Google, то приложение должно позволять локальный логин пользователя, нельзя привязывать приложение к аутентификации глобально. В редких случаях при такой необходимости нужно создавать мост для серверной части, которой делегировать любые операции с закрытой частью API.
    Ответ написан
    Комментировать
  • Как переместить значение из функции ниже по коду, сделать глобальным в js?

    gscraft
    @gscraft
    Программист, философ
    Это удивительный вопрос! Обычно наоборот, начинающие пытаются понять, почему переменная доступна вне функции.
    var a = 0; // переменная, объявленная снаружи, всегда доступна вглубь
    function foo () {
      b = 1; // b объявлена как window.b и доступна везде
      var c = 2; // переменная доступна внутри функции
      let d = 3; // переменная доступна внутри блока { }, где объявлена
    }
    // a == 0
    // b == 1
    // c == undefined
    // d == undefined

    А вообще, читайте документацию, mdn, например.

    PS Не используйте глобальные переменные. Лучше найти другое решение, связать классы, функции в единую среду выполнения.
    Ответ написан
    Комментировать
  • Почему не работает innerHTML?

    gscraft
    @gscraft
    Программист, философ
    Полагаю, библиотека JSDOM не меняет исходный файл. Вам нужно получить HTML после изменения элемента и передать этот HTML как ответ. Например,

    function getCards() {
      // ... некий код
      return dom.window.document.innerHTML;
    }
    // в обработчике маршрута:
      const html = getCards();
      res.send(html);
    Ответ написан
    6 комментариев
  • Как определить MIME-тип файла по содержимому?

    gscraft
    @gscraft
    Программист, философ
    Хм, определить MIME можно двумя способами: по расширению файла, если оно указано корректно, и по его содержимому. Если с расширением файла все просто, то файл придется читать, пытаясь сверить первые байты с имеющейся базой сигнатур форматов. Наверняка есть готовые библиотеки.
    Ответ написан
  • Как можно избежать дублирование кода?

    gscraft
    @gscraft
    Программист, философ
    Масса способов. Самое простое, добавьте активным элементам общий класс и работайте с ним, а не с tabs или subTabs, tabs-triggers__item или subtabs-triggers__item раздельно. Плюс, Вам достаточно внести разницу, если она вообще нужна, только в корневой элемент, а не делать различными все классы по иерархии: subtabs-content__item и tabs-triggers__item — лишнее усложнение, достаточно tabs_trigger__item в обоих случаях. Чтобы задать разные стили, достаточно разделять по родителю, а точнее, задать особенности для дочерних вкладок. Плюс, Вам необязательно делать вкладки вложенными друг в друга, можно расположить их друг под другом. Что касается JS, не вызывайте функцию раньше, чем она объявлена, и лучше обернуть от глобальной области видимости:
    function initTabs() {
      // здесь весь нужный код
    }
    document.addEventListener('DOMContentLoaded', initTabs);
    Ответ написан
    Комментировать
  • Почему XMLHttpRequest.getAllResponseHeaders() не показывает мои собственные кастомные заголовки?

    gscraft
    @gscraft
    Программист, философ
    Не все заголовки доступны из сценариев в случае разных доменов / cross-origin, для контроля этого существует специальный заголовок Access-Control-Expose-Headers, Вам нужно с сервера отправить 'Access-Control-Expose-Headers' с 'Abra-Kadabra'
    Ответ написан
    1 комментарий
  • Есть ли компиляторы для javascript?

    gscraft
    @gscraft
    Программист, философ
    Есть масса технологий разной степени готовности и области применения. Тут главный вопрос, чего Вы хотите получить и в каком окружении JavaScript? Браузер? Сервер Linux / NodeJS? Приложение рабочего стола? Это надо искать и пробовать. Навскидку, WebAssembly, JScript .NET, NectarJS или, скажем, Electron Packager. Ну и в ответе Алексей Уколовупаковщики.
    Ответ написан
    Комментировать
  • Почему пустой массив после запроса в базу данных sqlite?

    gscraft
    @gscraft
    Программист, философ
    У Вас в коде ворох неразберихи. Во-первых, дело не в запросе. А проверить запрос очень просто: логгируйте результат запроса в теле замыкания, где получаете player (можно заодно посмотреть, что хранится в members). Во-вторых, почему не выбрать сразу всех одним запросом? Запросы в цикле — моветон и лишние расходы. Предполагается
    const playerIds = channel.members.map(member => member.id);
    // Тут лучше использовать подстановку значений, см. документацию клиента базы данных
    const sql = `SELECT * FROM players WHERE user_id IN (${playerIds.join(',')})`;
    db.all(sql, (err, players) => resolve(
      players.map(player => `[**${player.level}**] ... ваша строка с пользователем ...`)
    ));

    В-третьих, players нужно определить внутри обещания, в теле Promise. В-четвертых, где и как Вы смотрите результат? Что и как получает ответ от return new Promise? Я полагаю, что у Вас это выглядит примерно так:
    function getPlayers() {
      // ...
      return new Promise(resolve => {
         // ...
         resolve(players);
      });
    }
    
    getPlayers().then(players => console.log(players));
    // или, если getPlayers() объявлено как async
    let players = await getPlayers();

    — то есть, Вы действительно получаете список игроков как результат Promise?
    Ответ написан
  • Цикл убивает браузер?

    gscraft
    @gscraft
    Программист, философ
    Видимо раньше Вы внутри цикла выполняли полезную нагрузку и отдавали рабочие ресурсы процесса между делом, сам того не подозревая. Везде, где используют бесконечный цикл, а не пользуются системой сообщений-событий для организации программы — организуют раздачу сообщений или таймаут вручную в обязательном порядке. Возьмите для примера приложения на Win API:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    — здесь цикл подвисает до получения сообщений от системы. Ну или другой пример (что пришел в голову), Python Pygame:
    while True:
      # код приложения
      tick(60) # отдадим время свыше необходимого фреймрейта системе

    Ну а на JS делать такое — моветон, совершенно неправильно. Поскольку любое JS приложение должно быть событийно-ориентированным, реагировать на действия пользователя, как и большинство UI-приложений. Если Вам нужно выполнять действие с интервалом, используйте:
    function main() {} // вместо Вашего напрасного цикла
    setInterval(main, 50); // вызывайте каждые 50 миллисекунд, например
    Ответ написан
    2 комментария
  • Как отправить тело запроса с переносами строк?

    gscraft
    @gscraft
    Программист, философ
    Отображается без переносов где? Перенос строки — это символы, отображаемые собственно как новая строка, в Windows — \r\n (возврат каретки и новая строка по подобию печатных машин), практически во всех остальных случаях — \n. Вы можете легко проверить, что содержится в textarea, открыв текст в Блокноте, который не поддерживает \n. Ну или программным путем, /\r\n+/.test(textareaText):
    xpkTcSh.png
    По всей видимости отображение на каком-то из этапов меняет подход к переносам строк (где просматриваете строки базы данных?), но если программно этого не меняете, текст должен оставаться в том же виде.
    Ответ написан
    5 комментариев
  • Как вывести массив строк в textarea построчно?

    gscraft
    @gscraft
    Программист, философ
    document.getElementById('your-textarea').value = yourStringList.join('\n');
    Ответ написан
    1 комментарий
  • Зачем нужны шаблонизаторы в Node.js?

    gscraft
    @gscraft
    Программист, философ
    Это классический подход для любых серверных технологий на PHP, NodeJS, Python, Go, C#, Java и т.д.. По сути есть всего-лишь три варианта для работы веб-приложения: 1) статические данные, когда нечто выдается 1 в 1, HTML, JS, медиа-содержимое 2) динамические данные, когда они формируются стороной сервера и 3) клиентские приложения, когда сервер выдает данные, а формирование отображения и интерфейса происходит на клиенте. Есть так же гибридный подход, когда страницы подгружаются кусками или часть отображения формируется на клиенте.

    Первый подход можно не рассматривать, он сосуществует, а второй — наиболее распространен. Поскольку большая часть сайтов имеют динамическое содержимое, будь то форум, лента новостей, магазин и т.д., все формируется из базы данных и на сервере. Третий подход все больше распространяется, во-первых, потому что нагрузка на сервер ниже, ниже объем передаваемых данных, во-вторых, потому что как правило клиентское приложение быстрее, но такой подход имеет много ограничений и в общем случае слабо совместим банально с поисковыми машинами. Поэтому использование шаблонизаторов, как способа формировать HTML (и другие вещи) на стороне сервера пока еще основной подход в вебе. Попробуйте хотя бы вывести ленту новостей на главную страницу, обойдясь без этого.
    Ответ написан
    Комментировать
  • Почему moment выводит год неправильно?

    gscraft
    @gscraft
    Программист, философ
    moment для инициализации через "конструктор" moment(...), как и Date в JS, использует метку времени с миллисекундами, чтобы получить объект из unix-метки с секундами, используйте moment.unix(...), этот нюанс стоит учитывать при работе с API, убедиться, какую возвращаете метку.
    Ответ написан
    Комментировать
  • Как сделать переход на другую страницу если имя и пароль верно?

    gscraft
    @gscraft
    Программист, философ
    На какую страницу и зачем хотите перейти? Логин и пароль не собираетесь отправлять на сервер? Я почему уточняю, если дело в этом, то нужно форме добавить атрибут action="/login-form/handler/url" и, по всей видимости, method="post". Ну или перехватить обработку формы / нажатия на произвольную кнопку и отправить данные через AJAX. Если же ничего делать с логином и паролем не собираетесь, то в JS это window.location.href='новый адрес';
    Ответ написан
    2 комментария
  • Как поправить setInterval в javascript?

    gscraft
    @gscraft
    Программист, философ
    Так Вы, похоже, не делаете clearInterval(countInterval); когда выполняется условие по счетчику? И потом, если используете jQuery, анимировать можно и без таймера, навскидку:
    const animate = ($elements, index) => {
      if (index < $elements.length)
        $elements.eq(index).animate({...}, {...}, () => animate($elements, index+1));
    }
    animate($(selector), 0);

    — jQuery сам анимирует, а по завершению цикла анимации вызовет обработчик, куда передаем следующий шаг (который можно сформировать любым удобным образом, в данном случае некая условная анимация элементов по списку), а когда индекс выйдет за границы селектора — вызова не будет, выполнение завершится.
    Ответ написан
    3 комментария
  • Обратный отсчет до определенной даты?

    gscraft
    @gscraft
    Программист, философ
    Ну, очень удобно пользоваться библиотеками вроде moment, luxon, в плане сравнения, API итерации дней и т.д., но можно воспользоваться и стандартным Date, в стандартной библиотеке JS класс даты-времени классный : ) В качестве примера:
    let source = new Date('2020-09-06 07:02:00');
    let current = new Date();
    while (source.getTime() > current.getTime())
       current.setDate(current.getDate() + 1); // просто добавляем дни

    — считать можно в обе стороны и в любой момент получить любые части даты.

    Если Вам нужно вывести что-то в духе "осталось столько-то дней":
    let source = new Date('2020-09-06 07:02:00');
    let current = new Date();
    let diff = new Date(source.getTime() - current.getTime());
    let empty = new Date(0);
    console.log('Months remains:', diff.getMonth() - empty.getMonth());
    let days = diff.getDate() - empty.getDate();
    let hours = diff.getHours() - empty.getHours();
    console.log('Days remains:', hours < 0 ? days - 1: days); // это справедливо и для месяцев, дней
    console.log('Hours remains:', hours < 0 ? 24 + hours : hours);

    — это решение придумал на ходу, возможно предложат эффективнее.
    Ответ написан
    2 комментария
  • Как такое сверстать?

    gscraft
    @gscraft
    Программист, философ
    А в чем проблема-то? Верстайте отдельные блоки, в которых полоса и круг по центру, сверху требуемый текст, и т.д., задайте блоку разные CSS-состояния, .step-completed, .step-selected, .step.-empty, .step-hidden, .step-first, .step-last и т.д., немного напишите на JS, чтобы при клике менять классы.

    Чтобы блоки прокручивались по необходимости, их нужно завернуть в еще один блок, которому задать свойство: overflow: visible (потомкам inline-block или с flex-column & flex-wrap: nowrap), а его завернуть в еще один, которому ограничить ширину и задать свойство overflow-x: auto, это классический подход.

    Тут просто рутина, какие-то под-задачи может вызовут вопросы, но если что, пишите в комментарии.
    Ответ написан
    Комментировать
  • Как сделать сортировку массива объектов по имени(name)?

    gscraft
    @gscraft
    Программист, философ
    Используйте https://developer.mozilla.org/ru/docs/Web/JavaScri... (на правах примера):
    let array = []; // Ваш JSON, полученный через Ваше API
    array.sort(function compare(a, b) {
      if (a.name === b.name) return 0;
      return a.name < b.name ? -1 : 1;
    });
    Ответ написан
    Комментировать
  • Как сделать редирект после заполнения формы?

    gscraft
    @gscraft
    Программист, философ
    Редирект делает браузер, Вам нужно отправить заголовок Location: header("Location: /{$url}", true, $status); — однако, стоит учитывать, что это может не сработать с некоторыми ajax-библиотеками, там уж смотрите по обстоятельствам.
    Ответ написан
    Комментировать
  • Как подобное можно сверстать?

    gscraft
    @gscraft
    Программист, философ
    Самостоятельно вряд ли напишете, берите любой физический движок и разбирайтесь с ним, например: https://github.com/wellcaffeinated/PhysicsJS или https://brm.io/matter-js/ — там есть демки с подобной функциональностью. Вес решений не берусь оценивать, думаю, можно найти и более минималистичные или позволяющие дробить функционал.
    Ответ написан
    Комментировать