Ответы пользователя по тегу JavaScript
  • Как скрыть блоки но открыть если в нем есть span?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Определить CSS класс .hidden { display: none; }
    И выполнить:
    document.querySelectorAll('li')
      .forEach(li => li.classList.toggle('hidden', !li.querySelector('span')));
    для каждого элемента списка устанавливает или снимает класс hidden, в зависимости от того, найдётся ли span где-нибудь внутри этого элемента.
    Ответ написан
    Комментировать
  • Как из float32 изображения сделать jpg?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Наивный ответ без учёта всех возможных косяков из-за неполноты вопроса:

    const tensor = tf.squeeze(result);
    
    const canvas = document.createElement('canvas');
    canvas.width = tensor.shape.width
    canvas.height = tensor.shape.height
    await tf.browser.toPixels(tensor, canvas);
    
    const cat2 = document.createElement('img');
    cat2.src = canvas.toDataURL();
    Ответ написан
  • Как можно вывести все целые числа от 1 до 100, квадрат которых не превышает числа N?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Идея: взять корень квадратный из N и вывести все от 1 до 100, что меньше или равны сему корню.

    Math.sqrt(N)

    Вообще, конечно, можно и..
    Генераторами!
    // дизель* генератор
    const ltSqr = function*(n) {
      const limit = Math.min(100, Math.sqrt(n));
      let i = 1;
      while (i <= limit) {
        yield i++;
      }
    }
    
    // использование
    let N = 42;
    for (const x of ltSqr(N)) {
      console.log(x);
    }
    // выведет натуральные от 1 до 6
    Ответ написан
    Комментировать
  • Sweet Alert добавил гимн Украины на сайт. Как убрать его из кода?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Рекомендуют использовать предыдущие версии 11.0.0 - 11.4.8

    https://github.com/advisories/GHSA-qq6h-5g6j-q3cm

    Например, попробуйте включать точную версию:
    https://cdn.jsdelivr.net/npm/sweetalert2@11.4.8
    Ответ написан
    1 комментарий
  • Как передать данные в корзину в виде массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Товары удобно держать в "словаре": ключ id, значение объект товара.
    Корзину – как тоже "словарь": ключ id товара, значение – количество в корзине.
    Количество товара стало 0 или меньше – удаляем ключ из Корзины.
    Так всё становится довольно однозначно.

    Отрендерить товары – нужна одна функция делающая для 1 товара из данных – HTML.
    То же для товаров в корзине.

    Нажали плюс-минус: меняется количество в Корзине, и её всю целиком заново рендерим.

    Общий принцип: данные → отрисовка по ним UI → действия пользователя меняют данные (и далее по кругу).

    data-атрибуты, наверное, лишние, раз и так вешаем прямо обработчик клика – в него же сразу и id товара пропишем.
    Ответ написан
    2 комментария
  • Есть 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 комментария
  • Как написать функцию, которая возвращает массив индексов элементов, у которые значение равно 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
    Ответ написан
    Комментировать
  • Нужно в 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 комментариев