Задать вопрос
  • Объясните в чем тут проблема?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пользуйтесь консолью – это бесплатно, спортивно, современно!
    console.log(this); // window
    В вашем коде this не принимает значение кнопки, а наследует его из внешнего кода. В данном случае, глобального, поэтому this === window

    Вероятно, вы ожидали, что this будет нажатой кнопкой. Так бы работало без стрелочной функции, если по-старинке передавали function(evt) {}
    Ответ написан
    Комментировать
  • Как получить access_token с правом app_widget?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Виджеты сообществ — документация
    0. Получение ключа доступа
    Для работы с виджетами в сообществе необходимо получить токен сообщества с правом доступа app_widget при помощи события VK Connect: VKWebAppGetCommunityAuthToken в приложении с типом VK Mini Apps.


    Создайте приложение ВК типа VK Mini Apps.

    Понадобится библиотека VK Connect: npm install @vkontakte/vk-connect

    И что-то вроде такого в index.js:
    import connect from '@vkontakte/vk-connect'; 
    
    // Sending event to client
    connect
      .sendPromise('VKWebAppGetCommunityAuthToken', {
        "app_id": 6909581, // id вашего свежесозданного mini App
        "group_id": 1,  // id группы, где вы админ, куда виджет
        "scope": "app_widget"
      })
      .then(data => {
        // Обработка события в случае успеха
        console.log(data);
      })
      .catch(error => {
        //Обработка событияв случае ошибки
      });
    Затем, наверное, webpack'ом билдится готовый скрипт, который подгружается в браузер.

    При этом сам токен вы не получаете, не сохраняете, не копируете. Просто теперь у этого VK Mini App'а вашего есть права на обновление кода виджета в вашем сообществе.
    Ответ написан
    Комментировать
  • Как проверить находится ли пользователь на открытой вкладке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Есть Page Visibility API (на англ.)

    Оттуда пример кода, который приостанавливает воспроизведение видео, если таб стал неактивным:
    spoiler
    // Set the name of the hidden property and the change event for visibility
    var hidden, visibilityChange; 
    if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 
      hidden = "hidden";
      visibilityChange = "visibilitychange";
    } else if (typeof document.msHidden !== "undefined") {
      hidden = "msHidden";
      visibilityChange = "msvisibilitychange";
    } else if (typeof document.webkitHidden !== "undefined") {
      hidden = "webkitHidden";
      visibilityChange = "webkitvisibilitychange";
    }
     
    var videoElement = document.getElementById("videoElement");
    
    // If the page is hidden, pause the video;
    // if the page is shown, play the video
    function handleVisibilityChange() {
      if (document[hidden]) {
        videoElement.pause();
      } else {
        videoElement.play();
      }
    }
    
    // Warn if the browser doesn't support addEventListener or the Page Visibility API
    if (typeof document.addEventListener === "undefined" || hidden === undefined) {
      console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
    } else {
      // Handle page visibility change   
      document.addEventListener(visibilityChange, handleVisibilityChange, false);
        
      // When the video pauses, set the title.
      // This shows the paused
      videoElement.addEventListener("pause", function(){
        document.title = 'Paused';
      }, false);
        
      // When the video plays, set the title.
      videoElement.addEventListener("play", function(){
        document.title = 'Playing'; 
      }, false);
    
    }
    Ответ написан
  • Как в гугл таблице скопировать данные из одного листа в другой?

    Можно использовать метод Range.copyTo()

    function myFunction() {
      var sourceSheet = SpreadsheetApp.getActiveSpreadsheet(); //лист откуда берем данные
      var activeRow = list1.getActiveSheet().getActiveCell().getRow(); //номер активной ячейки
    
      var destSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Журнал ввода данных");
      var lastRow = destSheet.getLastRow();
      destSheet.insertRowAfter(lastRow);
      var destRow = lastRow + 1;
      
      function copyCell(colFrom, colTo) {
        sourceSheet.getRange(activeRow, colFrom).copyTo(destSheet.getRange(destRow, colTo));
      }
                                                                                                          
      copyCell(1, 1); // номер участка
      copyCell(2, 2); // имя человека
      copyCell(4, 3); // дата начала работ
      copyCell(6, 4); // дата завершения работ
    }


    Добавить вызов этой функции в собственное доп. меню, можно так:
    function onOpen(e) {
      SpreadsheetApp.getUi()
          .createMenu('Работа с Журналом')
          .addItem('Копировать в журнал', 'myFunction')
          .addToUi();
    }
    Ответ написан
  • Три игральные кости подбрасывают по одному разу. которая вероятность того, что при этом все числа на трех гранях будут разными?

    Можно нарисовать дерево вариантов:
    5de56ffb5a740263340270.png

    1. A – первый бросок, тут устроит любой вариант из 6, поэтому 6/6
    2. B – второй бросок. Тут не подойдёт вариант, совпадающий с выпавшим в А. 1/6 отваливается, остаётся 5/6
    3. C или D – третий бросок (наш - C) Тут из 6 вариантов устроят только 4. 4/6


    Остаётся перемножить:
    6/6 * 5/6 * 4/6 = 120/216 = 5/9
    Ответ написан
    Комментировать
  • Nginx вынести страницу на поддомен?

    server {
      server_name catalog.site1.ru;
      location / {
        pro xy_pass http://site1.ru/catalog?date_from=&date_to=;
      }
    }

    Подробнее см. Модуль ngx_http_pro xy_module

    (Тостер режет любые упоминания про кси, поэтому с пробелами)
    Ответ написан
  • Становится ли контейнер образом?

    1. верно
    2. ок
    3. нет. docker build (док) создаёт новый image (образ) В вашем примере с тегом python-barcode
    4. docker run запускает из образа контейнер. Можно и не один, а несколько, даже параллельно. В вашем примере имя для него сгенерится автоматом, какая-нибудь смешная комбинация двух слов. Контейнер может работать, останавливаться, перезапускаться. Можно удалить контейнер. Контейнер не изменяет образ, из которого создан – он «накатывает» свою деятельность поверх, в новых слоях.
    5. контейнером не поделиться. Делятся образом. Если в контейнер вносили изменения - например, зашли в него терминалом, установили доп. пакеты – можно из этого контейнера создать новый image через docker commit


    базовый FROM образ -- образ с доп. слоями = ваш новый образ -- контейнер и изменения -- образ с изменениями
    Ответ написан
    2 комментария
  • Как связать несколько сайтов к одному IP?

    Все запросы должен ловить единый сервер, например, nginx.
    По заголовкам запросов Host: ... перенаправлять/проксировать запрос на соотв. виртуальный сервер.

    server {
      server_name site.ru;
      location / {
            proxy_pass http://127.0.0.1:8000; # допустим, тут слушает основной
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            # ... ещё инструкции - передача заголовков, кэширование..
        }
    }
    
    server {
      server_name name1.site.ru;
      location / {
          proxy_pass http://127.0.0.1:8001; # вирт-1
          # ...
      }
    }
    
    server {
      server_name name2.site.ru;
      location / {
          proxy_pass http://127.0.0.1:8002; # вирт-2
          # ...
      }
    }
    Ответ написан
    Комментировать
  • Где найти энтузиастов в разработке интересных проектов?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    По сути вы вампир, которому нужны жертвы. Это нормально. Проще их уболтать, обмануть укусить, увлечь в оффлайне: личной харизмой, обаянием и жестикуляцией с легким алкоголем. Так вероятнее получится собрать небольшую секту своих апостолов и дойти до скорой Голгофы. Ну, или первого раунда.

    Оффлайн зазнакомиться с целевой аудиторией можно на местных митапах по теме.
    Ответ написан
  • Как в docker работать с несколькими проектами?

    sergiks
    @sergiks Куратор тега Веб-разработка
    ♬♬
    все на php7.3, mysql 5.7, nginx

    Раз у всех проектов одна среда, достаточно запустить по одному инстансу php-fpm, mysql, nginx и пользоваться ими из всех разрабатываемых проектов.

    «Проект», получается, это папка с файлами, отдельная бд или таблицы на общем сервере MySQL, и прописанный в конфигах nginx
    location /project-42 { root /projects/project-42; ... }
    
    ### или целый блок
    
    server {
      listen 80;
      server_name  project42.dev;
      ... 
    }


    Пожалуй, лучше работать через docker-compose: весь конфиг в одном файле, общая сеть, сервисы друг друга видят, но при этом не светят лишними портами наружу.

    Поднимите сначала один из проектов. Потом разберитесь, как добавить файлы остальных через volumes:
    nginx:
      volumes:
        - "/freelance/projects/Project-0/:/var/www/project0"
        - "/freelance/projects/Project-42/:/var/www/project42"
        # ...
    php-fpm:
      volumes:
        # то же самое сюда


    2) Как проектам дать не localhost:8080, а нормальный урл типа project.dev?

    В конфиге сервиса nginx в docker-compose.yml пропишите вместо 8080:8080:80, а в локальном файле hosts допишите 127.0.0.1 project.dev project42.dev
    Ответ написан
    Комментировать
  • Как узнать элемент с которого начинаются цифры в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вот такая колбаса вернёт массив, где только «правильные» числа:
    [10, 20, 30, 50, 235, 3000].filter(n => !!~[1,2,5].indexOf(+n.toString()[0]))
    // результат  [ 10, 20, 50, 235 ]
    Вывод на экран пилите самостоятельно.

    Метод массива filter() оставит только те элементы, для которых функция внутри вернёт true. Функция аргумент (в скобках) применяется по очереди к каждому элементу массива (числу).
    Переводит число в строку, забирает первй символ (первую цифру) и переводит опять в число (оператор +).
    indexOf() ищет полученную первую цифру в массиве допустимых: 1, 2, 5 и возврашает его индекс (0, 1 или 2) или -1, если не найдено.
    Битовое инвертирование ~ из -1 сделает 0. А из любого другого числа (из 0, 1 или 2) – сделает ненулевое число. Два !! это два булевых оператора отрицания. Из аргумента делают true или false. Из 0 получится false, из любого другого true. Таким образом связка !!~ и indexOf() даёт ответ на вопрос найден или не найден?
    Ответ написан
    Комментировать
  • Как получить индексы выделенной подстроки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    См. как работать с Selection API.

    Метод getRangeAt() вернёт диапазон Range. Выделенных фрагментов может быть и несколько, но в вашем примере понадеемся на единственный getRangeAt(0)

    У объекта диапазона Range есть свойства startOffset и endOffset – то, про что спрашиваете.

    Ответ написан
    7 комментариев
  • Импорт и экспорт объектов в Javascript. В чём проблема?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    попробуйте с webpack
    Ответ написан
    Комментировать
  • Как сделать так что бы шахматная фигура по клику перемещалась на другую ячейку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно разделить данные и их отрисовку. Массив «состояния» доски: какая фигура в какой ячейке. Пустая клетка – пустая строка. Клетка с королевой – 'Q'. И функция, которая отрисовывает всю доску, исходя из Состояния.

    Для обозначения фигур использовать буквы из шахматной нотации. King = K, Queen = Q, Bishop = B, Knight = N, Rook = R, pawn = p
    Понадобится словарь, где ключу фигуры соответствует символ для его отображения.

    Каждая ячейка кликабельна. Кнопка в себе хранит координаты X и Y – понадобятся в обработчике клика, общем для всех.
    Хранится переменная для предыдущего. Изначально пуста. Если кликнули по фигуре, а «предыдущая» пуста, значит это Первый клик - выбор фигуры для хода.
    Второй клик должен выбрать другую ячейку, куда поставить выбранную ранее фигуру, или отменить выделение, если Второй раз выбрана та же клетка, что в Первый.

    Ответ написан
    7 комментариев
  • Как проверить подписан ли пользователь на канал YouTube при организации вип доступа?

    Нужно попросить пользователя авторизоваться через ваше приложение в YouTube и дать разрешение youtube.readonly на доступ к своим данным.

    См. метод YouTube Data API subscriptions:list. Обратите внимание на пример «check whether a subscription exists» – как раз ваша задача, и есть примеры кода, в т.ч. на PHP (прокрутите вправо).

    Для работы c PHP понадобится установить Google PHP SDK: composer require google/apiclient:^2.0, в API консоли создать проект, создать OAuth ключ, скачать его JSON.
    Ответ написан
    Комментировать
  • Вернуть программу в исходное состояние методом reset?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно пройтись по всем текстовым инпутам в секции и дать им value=""
    function reset() {
      [...document.querySelectorAll('section.main input[type="text"]')]
        .forEach( el => el.value='' )
      ;
    }


    Пара общих замечаний
    • Вместо
      document.getElementsByClassName('budget_day-value')[0]

      лаконичнее document.querySelector('.budget_day-value')
    • Пояснительный текст к каждому input'у семантически корректнее оборачивать в тег <label>, и либо указывать id инпута в атрибуте for="", либо включать инпут внутрь этого лейбла. Так клик по названию поля сделает фокус внутри этого поля.

    Ответ написан
  • Как вычесть процент с минимальной погрешностью?

    «вычесть 6.51%» на первом шаге оставит (100% - 6.51%) = 93.49%; операция равносильна умножению на 0.9349

    «вычесть из получившегося 6%» оставит от него 94%, что равносильно умножению «получившегося» на 0.94

    Обе операции: x * 0.9349 * 0.94 = x * 0,878806 без погрешностей, точно.

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Чтобы понять и понять правильно, можно прочитать целиком страницу про Closure на Learn JavaScript ru.

    Оттуда:

    Замыкания

    В программировании есть общий термин: «замыкание», – которое должен знать каждый разработчик.

    Замыкание – это функция, которая запоминает свои внешние переменные и может получить к ним доступ. В некоторых языках это невозможно, или функция должна быть написана специальным образом, чтобы получилось замыкание. Но, как было описано выше, в JavaScript, все функции изначально являются замыканиями (есть только одно исключение, про которое будет рассказано в Синтаксис "new Function").

    То есть, они автоматически запоминают, где были созданы, с помощью скрытого свойства [[Environment]] и все они могут получить доступ к внешним переменным.

    Когда на собеседовании фронтенд-разработчик получает вопрос: «что такое замыкание?», – правильным ответом будет определение замыкания и объяснения того факта, что все функции в JavaScript являются замыканиями, и, может быть, несколько слов о технических деталях: свойстве [[Environment]] и о том, как работает лексическое окружение.
    Ответ написан
    Комментировать
  • Перебор массива циклом for с целью обращения ко всем остальным элементам кроме i-го?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно проверять, равен ли очередной кандидат – кликнутому элементу:
    const onClick = event => {
      const nodeList = document.querySelectorAll('.item');
      for (let i=0;  i<nodeList.length; i++ ) {
        nodeList[i].style = (nodeList[i] === event.target ? 'background:red' : 'background:green');
      };
    }


    Лучше не пихать инлайн стили, а обойтись классами:
    .item {background: green } // по умолчанию все зелёные
    .item-red {background: red } // тот самый

    используя classList
    // clickedEl — item, по которому кликнули
    [...document.querySelectorAll('.item')].forEach(el => {
      if (clickedEl === el) el.classList.add('item-red');
      else el.classList.remove('item-red');
    });
    Ответ написан
  • Как установить фреймворк DEAP на Anaconda?

    На github DEAP/deap
    пишут про установку (Installation):
    pip install deap
    Ответ написан
    1 комментарий