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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    window.postMessage()

    У меня примерно так организована серверная OAuth2 авторизация в одном проекте. По клику «Войти через ХХХ» открывается новое окно, с URL авторизации в соц.сети с требуемыми параметрами. Там пользователь при необходимости логинится, даёт своё разрешение на доступ к данным. Его перекидывает на указанный URL на моём сервере с параметром &code=xxxxx, который уже мой сервер обменивает напрямую с соц.сетью на токен.

    При этом пользователю мой сервер в ответ на посадку с параметром code показывает какое-то минимальное содержание, главным образом, JS, который делает две вещи:
    • отправит postMessage() в родительское окно с основным приложением – сообщит о результате: получено разрешение или пользователь что-то накосячил или передумал;
    • закроет своё окно.


    Основное же окно после открытия дочернего с авторизацией, сидит, ждёт сообщение. Раз в секунду смотрит, существует ли ещё открытое дочернее окно, не закрыто ли оно (вдруг, пользователь психанул и просто закрыл то окно с авторизацией).
    Получив сообщение об успешной авторизации можно двигаться дальше.
    Получив сообщение об отказе авторизации или узнав, что дочернее окно просто пропало – вывести сообщение "так не пойдет, нужна авторизация. _Повторить?_"
    Ответ написан
    Комментировать
  • Как передать значение переменной в другую функцию, используя addEventListener?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Слушать события клика на всех элементах с классами .food-item-* (может, у них у всех есть какой-то общий класс?) или document.querySelectorAll('[class^=.food-item-]')

    При клике брать значение классов, похожих на .food-item-NNN-bin (регуляркой) и выдирать оттуда число.

    Но это, вестимо, костыль.

    Тут не хорошо, что значение класса используется не для отображения элемента, а для хранения каких-то его данных, этого самого числа. Класс обычно один-для-нескольких элементов. А для данных элемента есть data-атрибуты.
    Ответ написан
    4 комментария
  • В чем идея Mobile First подхода?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сумев обходиться малым, позволить себе больше — проще, чем обладая многим, начать ограничивать себя.

    То же длиннее и на англ. в посте.
    абзац
    Progressive Advancement has won the game for now as far as I can see. If UI/UX designers start a product design with its desktop version, they will inevitably want to make use of most of the advantages of the advanced end. For example, the hover effect which is supported by a cursor mouse; HD images & complex charts which can display normally only when there is a recent bandwidth. In this way, the designers will make efforts to complete an amazing desktop version and only to find it can hardly be adopted on a mobile end unless they give up a lot of beautiful ideas. If so, the mobile end version will be more like an afterthought, an incomplete product which’s been watered down.
    Ответ написан
    Комментировать
  • Как задать фон и цвет всем объектам по которым не произведён клик?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Аккуратнее вынести стили в CSS. Скажем, стили по умолчанию у всех и некий класс active для единственного выбранного элемента:
    div.answer { background: #222; color: #aeaeae; }
    div.answer.active { background: #fff; color: #000; }


    Тогда скрипт примерно такой:
    const els = [...document.querySelectorAll('.answer')];
    
    const toggle = event => {
      els.forEach(el => el.classList[event.target === el ? 'add' : 'remove']('active'));
    }
    
    els.forEach(el => el.addEventListener('click', toggle));

    Fiddle
    spoiler

    Ответ написан
    Комментировать
  • Не понимаю оператора return в JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Смотрите, как вызывать/использовать эту функцию.

    var a = getRectArea( 3, 4 );
    Тут в переменной a окажется значение, которое функция вернула – то, что после "return" в ней оказалось. В вашем примере это 3 * 4, т.е. число 12. Ура, в переменной a теперь лежит число 12

    И как только выполнился return – всё, дальше функция уже не выполняется, это был выход.
    function test() {
      return;
      alert('Привет мир!'); // эта строка никогда не выполнится
    }
    Ответ написан
    1 комментарий
  • Как добавить event listener?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сам gtag не предусматривает, чтобы слушали события на нём. Поэтому надо прошерстить весь свой код и найти все вызовы gtag() с искомым событием. И там же дописать ваш alert()
    Или сделать свою прослойку для аналитики. На странице вызывать вместо gtag() свою функцию, например, mytag() которая, в свою очередь, станет вызывать gtag() и может, другие скрипты аналитики.

    Upd. в комментариях выяснилось, что ТС не может поменять вызовы к gtag() В таком случае остаётся заменить функцию gtag() на свою:
    function gtag(){
      dataLayer.push(arguments); // это весь исходный её функционал
    
      if (arguments.length > 1
        && typeof arguments[0] === 'string'
        && arguments[0].toLowerString() === 'event'
        && typeof arguments[1] === 'string'
        && arguments[1] === 'name1'
      )
      {
        alert("Name 1!");
      }
    }
    Ответ написан
    4 комментария
  • Как работает этот алгоритм?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Тут как бы длинный поезд из смайликов и короткая видимая платформа остановки. В середине видны какие-то средние вагоны, а левый край поезда, определяемый переменной position – где-то далеко слева, его не видно, а значение position отрицательное. Ноль соответствует точно левому краю, началу видимой «платформы».

    Когда жмут prev – толпа смайликов едет вправо, её position увеличивается. Но при этом последний вагон не должен уехать правее левого края платформы. Поэтому position (обычно отрицательный) делается равным наибольшему из двух: 0 или вычисленному значению. Если «уехали», position получился положительным. И Math.min(0, position) станет равным 0.

    Та же механика с правым краем и движением «поезда» справа налево. Нельзя, чтобы правый вагон поезда уехал левее правого края платформы. Нельзя, чтобы показались пустые рельсы. Поэтому position не должен становиться левее == меньше, чем минус-длина поезда плюс длина платформы.
    Ответ написан
    3 комментария
  • Как делать пошаговые действия?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Поскольку всё в рамках одного домена/сайта, ограничения Same Origin Policy не помешают.

    Каждая открываемая страница – это новое свежее выполнение скрипта. Поэтому между переходами надо как-то сохранять «состояние» — например, в куках или LocalStorage. В некоторых настройках ни одно из этих хранилищ может оказаться недоступным – например, в зашоренном Tor-браузере.

    С использованием LocalStorage можно примерно так:
    const KEY_STATUS = 'status'; // ключ сохраняемого параметра
    const step = +localStorage.getItem(KEY_STATUS);
    
    /* 
      Шаги:
      0 - переход на /1
      1 - заполнение и клик (видимо, в переходом на новую страницу?)
      2 - переход на /2
    */
    if (0 === step) {
    
      document.location.href = "http://site.ru/1";
    
    } else if (1 === step) {
    
      document.getElementsByName("pw")[0].value = "test";
      document.getElementsByClassName("ur")[0].click();
    
    } else if (2 === step) {
      
      document.location.href = "http://site.ru/2";
    
    }
    
    localStorage.setItem(KEY_STATUS, 1 + step);
    Ответ написан
    7 комментариев
  • Математические вычисления с дробными числами?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    К счастью, у вас не банк с расчетом стаки по кредиту.

    Почему бы не считать все в копейках? Тогда все расчеты в целых.

    ..Пока маркетологи не захотят давать скидку в 1/3
    Ответ написан
    2 комментария
  • Как определить к какой форме принадлежит input?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Прикрутить бы VueJS, и сделать корзину реактивной: в любой из форм изменили число товара, везде так же изменилось.

    Костылинг мог бы быть с глобальным объектом, хранящим актуальную корзину. Любая из форм меняет значениеив нем. Сеттер значения эмитит событие, которе слушают все формы, чтобы обновить свои данные.
    Ответ написан
  • Возможно ли средствами css3 нарисовать такое?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Не пробовал, но стоит попробовать CSS свойство clip-path
    clip-path: rectangle(...)
    или mask-image и генерируемый SVG.

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Не полениться обходить каждое свойство, и если его значение это объект, то рекурсивно не полениться обходить...

    Простых-встроенных методов пока нет.

    Например, см. реализцию _.merge() в библиотеке lodash.
    Ответ написан
    Комментировать
  • Как укоротить данный код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Я бы предложил удлиннить на два дополнительных знака равенства:
    const bool = residential.is_brick === 0 || residential.is_brick === null;
    Ответ написан
    Комментировать
  • Безопасно ли передавать пароль через ajax?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    По протоколу HTTPS безопасно. По HTTP — опасно.
    Ответ написан
  • Как защитить приложение?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Обсуждение похожего вопроса на github Electron'а.

    Один из вариантов – написать на C++ собственный модуль для NodeJS, реализующий скрываемый функционал.

    В вопросе не описано, как работает приложение: полностью автономно или клиент-сервер. Необходимость общения с сервером значительно упростила бы контроль оплаты.

    Для автономного моё предложение: регулярно обновлять приложение, улучшая его с каждым релизом. При автообновлениях проверять статус подписки. Так «хакеры» лишились бы свежих версий.
    Ответ написан
    1 комментарий
  • Почему random не работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1.
    var x = [Math.floor(Math.random()*10)];
    // заменить на
    var x = Math.floor(Math.random()*10);


    2.
    if(x=input){
    // заменить на
    if(x==input){
    Ответ написан
  • Что почитать по авторизации на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    • cookies – JS умеет их читать и устанавливать, а back по ним узнаёт сессию
    • HTTP headers – с каждым AJAX-запросом можно передавать в заголовках параметры авторизации
    • window.postMessage() может пригодиться, чтобы из нового окна, в котором отправили пользователя авторизовываться через третью соц-сеть, сообщить в «основное» окно, как всё прошло.
    Ответ написан
    Комментировать
  • Почему цикл обрабатывается не верно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var i; // var в отличие от let и const «всплывает» наверх
           // поэтому можно записать и так.
           // Это важно, т.к. изменить i могут где-то ниже в коде.
    
    for(i=0; i<10; i++) { 
      setTimeout(function() { // на каждой итерации создаётся новая функция,
                              // которая сохраняет ссылку на переменную  i 
        alert(i);             // чтобы когда, наконец, сработает, 
                              // вывести что там в i окажется в тот момент
      }, 100); // выполнение откладывается на потом через 1/10 сек
    }

    Цикл доиграл, создал-отложил 10 функций-анонимусов, каждая пристально смотрит на переменную i.
    К этому времени i, спасибо циклу, уже выросла до значения 10.

    Через 0.1 секунды посыпятся выполняться те 10 функций,
    и каждая выведет текущее значение i на этот момент.

    Занимательный факт.
    Если после цикла дописать i = 2*2*5*0x65 ; то алёрты выведут наступающий год!
    Ответ написан
    Комментировать
  • Переменные создавать внутри или вне циклов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    for(let i = 0, a = document.querySelector(".elem"); i <10; i++) {
      alert(a);
      console.log(a);
    }
    Ответ написан
    3 комментария
  • Как автоматизировать процесс записи видео (ScreenCapture) для SVG-анимации?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вот вариант SVG animation to video:

    использовать Media Recorder API и скрытый элемент canvas

    Поскольку отрисовка кадров из элементов img может подтормаживать, этот код заранее генерит все кадры и после рендерит в цикле их через requestAnimationFrame()

    index.html
    <!DOCTYPE html>
    <meta charset="utf-8">
    <body>
    <svg width="960" height="500"></svg>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
    <script src="https://d3js.org/topojson.v2.min.js"></script>
    <script>
    var svg = d3.select("svg"),
        canvas = document.createElement("canvas"),
        width = canvas.width = +svg.attr("width"),
        height = canvas.height = +svg.attr("height"),
        context = canvas.getContext("2d");
    
    var projection = d3.geoOrthographic()
      .scale(195)
      .translate([width / 2, height / 2])
      .precision(0.1);
    
    var path = d3.geoPath().projection(projection);
    
    d3.json("/mbostock/raw/4090846/world-110m.json", function(err, world) {
      var data = [],
        stream = canvas.captureStream(),
        recorder = new MediaRecorder(stream, { mimeType: "video/webm" });
    
      recorder.ondataavailable = function(event) {
        if (event.data && event.data.size) {
          data.push(event.data);
        }
      };
    
      recorder.onstop = () => {
        var url = URL.createObjectURL(new Blob(data, { type: "video/webm" }));
        d3.selectAll("canvas, svg").remove();
        d3.select("body")
          .append("video")
          .attr("src", url)
          .attr("controls", true)
          .attr("autoplay", true);
      };
    
      var background = svg.append("rect")
        .attr("width", width)
        .attr("height", height)
        .attr("fill", "#fff");
    
      svg.append("path")
        .datum({ type: "Sphere" })
        .attr("stroke", "#222")
        .attr("fill", "none");
    
      svg.append("path")
        .datum(topojson.feature(world, world.objects.land))
        .attr("fill", "#222")
        .attr("stroke", "none");
    
      svg.append("path")
        .datum(topojson.mesh(world, world.objects.countries, function(a, b) {
          return a !== b;
        }))
        .attr("fill", "none")
        .attr("stroke", "#fff");
    
      var queue = d3.queue(1);
    
      d3.range(120).forEach(function(frame){
        queue.defer(drawFrame, frame / 120);
      });
    
      queue.awaitAll(function(err, frames){
        recorder.start();
        drawFrame();
    
        function drawFrame() {
          if (frames.length) {
            context.drawImage(frames.shift(), 0, 0, width, height);
            requestAnimationFrame(drawFrame);
          } else {
            recorder.stop();
          }
        }
      });
    
      function drawFrame(t, cb) {
        projection.rotate([360 * t]);
        svg.selectAll("path").attr("d", path);
    
        var img = new Image(),
            serialized = new XMLSerializer().serializeToString(svg.node()),
            url = URL.createObjectURL(new Blob([serialized], {type: "image/svg+xml"}));
    
        img.onload = function(){
          cb(null, img);
        };
    
        img.src = url;
    
      }
    });
    </script>
    Ответ написан
    Комментировать