• Есть 10 кнопок и как повесить на них функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    как вариант, можно слушать клики где-то выше, на общем родителе их всех, или вообще на document:
    document.addEventListener('click', ({ target }) => {
      if (target.classList.contains('services__buy')) {
        // do something
      }
    });
    Ответ написан
  • Почему при выносе массива из цикла в глобальную переменную, сортировка имеет разную вероятность?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    DISCLAIMER Реализации сортировки могут быть разными.

    Добавьте в функцию сортировки вывод итерации, a, b и полученного случайного результата.
    spoiler
    { // выполнить в консоли браузера
      const oneTest = () => {
        let iterations = 0;
        [1, 2, 3].sort((a, b) => {
          const result = Math.random() > Math.random() ? 1 : -1;
          console.log(`${iterations}: ${a} vs ${b} = ${result}`);
          iterations++;
    
          return result;
        });
    
        return iterations;
      }
    
      console.clear();
      const totalTests = 10;
      const stats = {};
      
      for (let test = 0; test < totalTests; test++) {
        console.group(`Test ${test + 1} of ${totalTests}`);
        const iterations = oneTest();
        stats[iterations] ??= 0;
        stats[iterations]++;
        console.groupEnd();
      }
      console.log(JSON.stringify(stats, null, 2));
    }

    Выводит шаги сортировки. И общую статистику: у меня вышло 5 раз по 3, 5 раз по 2 сравнения из 10.

    Иногда требуется 3 сравнения, если у первых двух разные знаки.
    Иногда достаточно двух, когда у первых двух сравнений знаки совпадают.

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Date.now()
    Начало времен — это единый момент.
    В это же время в вашем часовом поясе было на 2 часа больше, чем в Гринвиче. Но миллисекунды Unixtime всегда по UTC.
    Ответ написан
    Комментировать
  • Кнопка создать select?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Вывести данные для опций один раз, и положить их в константу:
    spoiler
    $options = [
        [null, $_LNG['TYPE_ORDER']],
        ['select_all', $_LNG['ALL_TYPES']],
        ['select_domain', $_LNG['DOMAIN']],
        ['select_server', $_LNG['SERVER']],
        ['select_ssl', $_LNG['SSL']],
        ['select_desing', $_LNG['DESING']],
        ['select_script', $_LNG['SCRIPT']],
        ['select_layout', $_LNG['LAYOUT']],
        ['select_adv', $_LNG['ADV']],
        ['select_seo', $_LNG['SEO']],
    ];
    
    printf('const options = %s;', json_encode($options));


    Вот такая JS функция динамически создаёт из этих options полноценный элемент select со всеми опциями:
    createSelect = () => {
      const select = document.createElement('select');
      options.forEach(([value, title]) => {
          const option = document.createElement('option');
          option.innerText = title;
          if (value) {
            option.value = value;
          } else {
            option.setAttribute('disabled', true);
            option.setAttribute('selected', true);
          }
          select.appendChild(option);
        });
      return select;
    };

    Создали селект – одновременно создаём кнопку, но пока её прячем. Референс на созданный селект и кнопку держим. По событию выбора в свежесозданном селекте – показать изначально скрытую кнопку "Добавить".

    Нажатие на кнопку создаёт ещё один селект-с-кнопкой.

    Ответ написан
    3 комментария
  • Как максимально недорого и просто сделать звуковой эффект эха аппаратно?

    размером с тумбочку

    Пружинный ревербератор! Одна (или несколько) длинных пружин, с одной стороны электромагнит создаёт колебания, с другой пьезодатчик их снимает, как вариант. Несложное устройство. Тёплый ламповый – вот это вот всё )
    фото
    1200px-Spring_Reverb_8325.jpg


    Звук, как я понимаю, снимать со стекла, с поверхности — тоже лучше пьезодатчиком. Купить для акустической гитары, например. Тогда постукивания по стеклу снимутся, а громкий динамик соседнего стенда меньше попадёт в сигнал.
    Ответ написан
    3 комментария
  • Как написать функцию, которая возвращает массив индексов элементов, у которые значение равно value?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    возвращает массив индексов элементов, у которые значение равно value.

    const findIndex = (arr, value) => arr
      .map((v, i) => ({ v, i }))
      .filter(({ v }) => v === value)
      .map(({ i }) => i);
    Каждый элемент массива переделать в объект, где v: элемент, а i: индекс в массиве.
    Затем отфильтровать, оставив только те, где бывш.элемент === value
    В конце вернуть вместо каждого оставшегося элемента только его индекс i
    Ответ написан
    2 комментария
  • Как вывести текст под инпутом, если он пустой?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Для отдельного поля:
    Вот пример
    Вот статья

    Кнопку отключать – держать общую функцию, которая будет проверять каждое из полей, и включать/выключать кнопку через setAttribute("disabled", true) в зависимости от заполненности всех. Слушателем события "input" на каждом из полей вызывать эту функцию.
    Ответ написан
    Комментировать
  • Как передать в функцию рендера html несколько массивов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Собрать промежуточный словарь, где ключи – id, а значения – массивы имён. Неважно, из тарифов или из pet'ов.
    Ответ написан
    2 комментария
  • Как осуществить jQuery.post() на чистом JavaScript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    используйте fetch()

    Пример
    Ответ написан
    Комментировать
  • Как хранить большие видео на сервере?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Нужен веб-сервер, который умеет в большие видео-файлы: отдавать не просто весь файл целиком, а находить в нём запрошенное время начала, и выдавать по небольшим кусочкам. См. DASH (на англ.)

    Чтобы играть видео можно было с любого места, не скачивая часовое видео полностью.

    Подробнее на примере NGINX (на англ.)
    Ответ написан
    Комментировать
  • Как можно оптимизировать данный код и сократить количество циклов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно подготовить для книг «оглавление»: объект, где ключи id книг, значения сами объекты книг.
    Затем останется заменить в массивах user'ов id книг на значения из словаря.
    const library = books.reduce((acc, c) => (acc[c.id] = c, acc), {});
    const result = users.map(user => {
      const books = user.books.map(id => library[id]);
      return { ...user, books };
    });
    Codepen
    Ответ написан
    Комментировать
  • Можно как-то отрефакторить данный код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если правильно понял, в массиве лежит «кольцо» точек. Первая соседствует с последней.
    И к любой выбранной точке надо добавить две новые, слева и справа, с усреднёнными с соседями координатами.
    function addPointCenter(index) {
      const avg = (a, b) => (a + b) / 2;
      const midPoint = (p1, p2) => ({ lat: avg(p1.lat, p2.lat), lng: avg(p1.lng, p2.lng) });
      const insert = (index, point) => latlng.splice(index, 0, point);
    
      const { length } = latlng;
      const current = latlng[index];
    
      const indexLeft = (index - 1 + length) % length;
      const pointLeft = midPoint(current, latlng[indexLeft]);
    
      const indexRight = (index + 1) % length;
      const pointRight = midPoint(current, latlng[indexRight]);
    
      insert(index + 1, pointRight);
      insert(index, pointLeft);
    
      drawMarkers();
    }
    Ответ написан
    1 комментарий
  • Как сделать динамическую длину ключей для обращения к объекту?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Есть готовые модули, например, rhalff/dot-object для работы с нотацией свойств через точку:
    dot.str('qna.habr.com', 'value', this.data);
    /* this.data: 
    {
      qna: {
        habr: {
          com: "value"
        }
      }
    } */

    Установка: npm install dot-object --save
    Ответ написан
  • Как вызвать следующий interval после смены флага?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно «подглядывать» за изменениями свойства объекта.
    Предлагаю не переменную isLoading, а свойство некого объекта изменять: flags.isLoading = false;

    const PERIOD = 5000;
    let timeout;
    
    const action = () => {
      console.log('Action!');
      // this.switchNextTab()
      clearTimeout(timeout);
      timeout = setTimeout(action, PERIOD);
    };
    
    const flags = {
      _isLoading: false,
    
      set isLoading(value) {
        this._isLoading = value;
        if (!value) {
          // isLoading стал false
          action();
        }
      },
    
      get isLoading() {
        return this._isLoading;
      },
    };
    
    timeout = setTimeout(action, PERIOD);
    
    // где-то в коде:
    flags.isLoading = true;
    // ...
    flags.isLoading = false; // тут же выполнится action
    Ответ написан
    Комментировать
  • Как убрать вывод нуля при $amount = 1?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Округление дело такое. При коэффециенте 0.25 как ни округляй, будет 0 для $amount < 2

    refactor
    $rand = mt_rand(1, 1000);
    $bad = '...';
    
    if ($rand < 150) {
        $k = 1;
        $message = '$ (x0) ❌';
    } elseif ($rand < 300) {
        $k = 0.75;
        $message = "$ (x0.25) $bad";
    } elseif ($rand < 450) {
        $k = 0.5;
        $message = "$ (x0.5) $bad";
    } elseif ($rand < 600) {
        $k = 0.25;
        $message = "$ (x0.75) $bad";
    }
    
    $delta = round($amount * k);
    $res = $user->balance - $delta;
    $restxt = 'Вы проиграли ' . number_format($delta, 0, '', '.') . $message;


    Если "бизнес-логика" настолько странная, что и округлять в меньшую сторону, и сделать исключение для 1 и только для неё, то
    $delta = $amount === 1 ? max(1, floor($amount * k)) : floor($amount * $k);
    но следующий вопрос будет «а вот 2 при $k === 0.25 тоже округляется до 0»
    Ответ написан
    1 комментарий
  • Нужно в js создать таблицу 10 на 10 чтобы 1 шли по диагонали. Остальное 0?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Когда там единицы и нули, я думаю о битах )
    Альтернативная диагональ:
    10 чисел, где включен только 1 бит – в двоичном представлении
    001
    010
    100
    Из каждой цифры (0 или 1) делается ячейка таблицы. Строки оборачиваются в тег tr, и всё это обёртывается в table. Полученный HTML вставляется в страницу.
    Ответ написан
    Комментировать
  • Как обернуть в теги некоторые слова в HTML?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробовал сделать через DocumentFragment, рекурсивный обход текстовых Node
    и обёртку найденных слов с помощью Range.surroundContents()

    Получилось как-то переусложнённо. Но наверное лучше, чем регуляркой HTML разбирать: не станет менять слова в атрибутах тегов. Раз уж это разметка, можно работать с DOM.
    Слабое место – не обошлось без регулярного выражения для поиска слов. Т.к. там кириллица, привычные \b для границы слова не работают, пришлось заглядывать впрёд-назад, и регулярка вышла некороткая.

    Криво-длинно, но работает:

    Из исходного HTML делается DocumentFragment — как DOM полноценного документа. Перебираются его узлы. Если узел не-текстовый, рекурсивно перебираем его дочерние узлы.
    В текстовых узлах ищем искомые слова.

    Найденное слово (по одному за раз) заменяется на обёртку с этим словом.
    Вместо 1 исходного текстового узла, у нас становится уже 3: текст-элемент-текст.
    Далее поиск повторяется с хвостовым остатком текста – третьим (текстовым) узлом, пока в тексте не останется искомых слов для замены.

    Решение не лаконичное и не простое. Если возникнут вопросы, пишите, постараюсь объяснить.
    Ответ написан
    7 комментариев
  • Как сравнить переменную с ключами объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно отсортировать по ключам по убыванию, и найти find() первый, где данное число окажется больше ключа.
    Если не нашлось такое, отдать последнее значение (с минимальным ключом).
    что за entries ?
    Object.entries(obj) делает из объекта массив пар [[ключ, значение], ... ] — 
    [
      [50: "3500"],
      [100, "6000"], 
      ...
    ]

    const findRange = n => {
      const obj = { 
        50: "3500", 
        100: "6000", 
        200: "8000", 
        300: "10500", 
        500: "13000", 
        501: "индивидуально" 
      };
      const lookup = Object.entries(obj).sort(([a], [b]) => b - a);
    
      return (lookup.find(([k, v]) => Number(k) <= n) ?? lookup.pop())[1];
    };
    
    findRange(49) // "3500"
    findRange(99) // "3500"
    findRange(100) // "6000"
    findRange(500) // "13000"
    findRange(501) // "индивидуально"
    Ответ написан
    Комментировать
  • Как правильно сделать зависящие друг от друга сетевые запросы с помощью Promise.allSettled?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Просто склейте их в одну цепочку. Что-то типа:
    макароны
    const state = {};
    const getJSON = response => response.json();
    getAuth()
      .then(getJSON)
      .then(({ id }) => {
        state.id = id;
        return getUser(id);
      })
      .then(getJSON)
      .then(user => {
        state.user = user;
      })
      .then(() => getOrder('users', state.id))
      .then(getJSON)
      .then(({ order }) => state.order = order)
      .catch(console.error)
      .finally(() => console.log("all done", state));


    возможна ли реализация данной логики с помощью Promise.allSettled?

    Нет. allSettled() параллелит выполнение всех промисов и дожидается, чтобы «все расселись» – будь то resolve или reject.

    Хотя, пожалуй, тут можно последние два запроса запараллелить. Они оба нуждаются сначала в авторизации, а затем могут идти независимо-одновременно.
    const state = {};
    
    // подготовка
    const getJSON = response => response.json();
    const getUser = id =>
      fetchUser(id)
        .then(getJSON)
        .then(({ user }) => (state.user = user));
    const getOrder = id =>
      fetchOrder('users', id)
        .then(getJSON)
        .then(({ order }) => (state.order = order));
    
    // поехали
    getAuth()
      .then(getJSON)
      .then(({ id }) => {
        state.id = id;
        return Promise.allSettled([getUser(id), getOrder(id)]);
      })
      .catch(console.error)
      .finally(() => console.log('all done', state));
    Ответ написан
    Комментировать
  • Как решить задачу по JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    function count(min, max) {
      let counter = 0;
      for (let n = min; n <= max; n++) {
        if (!n.toString(10).includes('5')) counter++;
      }
      return counter;
    }
    
    count(4, 17)  // 12
    Определять, есть ли в числе цифра 5 можно и иначе, без преобразования в строку, но так короче )
    Ответ написан
    Комментировать