Ответы пользователя по тегу JavaScript
  • Как проверить форму на введённый номер телефона?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    у поля ввода атрибут pattern должен быть: pattern="\+49[0-9]{10,11}"

    В валидации в showError() надо проверять свойство patternMismatch:
    } else if (phone.validity.patternMismatch) {
      phoneError.textContent = 'phone should be +49 followed by 10 to 11 digits';
    }
    Ответ написан
    1 комментарий
  • Как через цикл вложить элементы DOM один в другой?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно изнутри наружу идти:
    создавать очередной элемент и вкладывать в него предыдущий.
    Ответ написан
    Комментировать
  • Как достать из массива индекс удаленного объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Массивы с пустыми слотами называются sparse arrays. Разные методы массивов по-разному обходятся с пустыми слотами: более новые их считают undefined, старые методы пропускают.

    Топорное решение: собрать индексы присутствующих элементов, и сравнить с полным диапазоном индексов:
    const arr = [1,2,3,4,5,6,7,8,9];
    delete arr[1];
    delete arr[3];
    delete arr[5];
    // arr == [ 1, <1 empty slot>, 3, <1 empty slot>, 5, <1 empty slot>, 7, 8, 9 ]
    
    const present = [];
    arr.forEach((_, i) => present.push(i));
    // present == [ 0, 2, 4, 6, 7, 8 ]
    
    const empty = Array.from({ length: arr.length }, (_, i) => i) // [0,1,2,3,4,5,6,7,8]
      .filter(i => !present.includes(i));
    // empty == [ 1, 3, 5 ]
    Ответ написан
    Комментировать
  • Почем цикл do while вызывает зависание страниц браузера?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Предложил бы редуцировать измерения )
    свести двумерное поле к одномерной колбасе.

    Если поле 6x6, то это одномерный массив длиной 36 элементов. Каждый элемент — одна из клеток на поле.
    Номер элемента однозначно переводится в координаты (x, y), если известна длина стороны поля.

    Например, поле 6x6. Нумерация от нуля: 0..5 Число, допустим, 13.
    X = 13 % 6 = 1 
    Y = floor(13 / 6) = 2

    Теперь, из колбасы всех возможностей надо отобрать случайным образом сколько требуется случайных.

    В цикле брать один случайный элемент из оставшихся в колбасе. Причём забирать, вынимать его оттуда, сокращая массив оставшихся возможностей.

    Так не понадобится холостых повторных попаданий в ранее выбранные клетки. Не понадобится по два случайных генерить. Один рандом — одно 100% попадание.

    function generator(quantity, side = 6) {
      const length = side * side;
      if (quantity > length) throw new Error('too much u ask');
    
      const options = Array.from({ length }, (_, i) => i); // [0,1,2,3, .. ,35]
      const nToPoint = n => ({ x: n % side, y: Math.floor(n / side) }); // 13 => {x:1, y:2}
      return Array.from({ length: quantity }, () =>
        nToPoint(
          options.splice(Math.floor(Math.random() * options.length), 1).pop()
        )
      );
    }
    
    console.log(generator(4));
    // [{x:1,y:2}, {x:0,y:4}, {x:1,y:0}, {x:4,y:4}]
    Ответ написан
    Комментировать
  • Как передавать через стрелочки класс в JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Нумеровать поля можно парами (x, y), а можно сквозной нумерацией 0..8 как div'ы в контейнере.
    Понадобится перевод из одной системы в другую, и назад.

    Текущее состояние можно держать как сквозной номер активного дива.
    Стрелочки меняют (x, y) координаты.
    Не забыть перевести туда-сюда и отрисовать – удаляя/добавляя класс, в зависимости от номера дива.
    Ответ написан
    Комментировать
  • Как вставить текст туда куда мне нужно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В первой строке лишний бэк-тик в конце:
    textpayload = message.user.bonusNew ? `"{\"button\": \"дуэль\"}"` : "{\"button\": \"бонус_новичка\"}`"

    См. последние 2 символа: удалите `
    Бэк-тики (обратные кавычки) там вообще-то все не нужны, т.к. не используются их преимущества.

    Неблагодарное дело вручную писать JSON со всем эти кавычками – тут обычными, тут экранированные обратными слешами. Лучше сделать обычный объект, и потом его перевести в строку JSON:
    const bonusButton = { button: message.user.bonusNew ? 'дуэль' : 'бонус_новичка' };
    textpayload = JSON.stringify(bonusButton);
    Ответ написан
    Комментировать
  • Как дождаться выполнения промиса?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    попробуйте заморозить локейшн, чтобы ни один редирект не проскочил:
    Object.freeze(location);

    Upd. раз хочется, чтобы всё-таки отработал и оригинальный клик с редиректом, можно так:
    1. повесить свой слушатель клика, в котором останавливать событие клика. Т.к. наш слушатель позже — он переиграет исходный слушатель разработчиков.
    2. после отрабатывания нашего долгого скрипта, удалить свой слушатель, и снова вызвать событие клика на кнопке — теперь его отловит оригинал с редиректом.


    Ответ написан
  • Как вывести нужный элемент по клику?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Короткий пример с данными из data-атрибутов,
    и единственным слушателем клика — на общем родителе:

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Достаточно при изменении значения поправлять его, когда вылезает за 80:

    Ответ написан
    Комментировать
  • Можно ли переопределить оператор присваивания у объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно с помощью «сеттеров» — функции, которая вызывается, когда объекту назначают это свойство.

    Например, в классе определить метод, который будет вызываться при установке значения свойству:
    class Habr {
      __values = [];
    
      static delimiter = ';';
    
      get qna() {
        return this.__values.join(Habr.delimiter);
      }
    
      set qna(value) {
        if (!this.__values.includes(value)) {
          this.__values.push(value);
        }
      }
    }
    
    const foo = new Habr();
    foo.qna = 'x=y';
    foo.qna = 'a=b';
    console.log(foo.qna); // x=y;a=b


    Для ранее существовавшего объекта можно переназначить его свойство, вписав сеттер через Object.defineProperty()
    Ответ написан
    1 комментарий
  • Как покрасить текст в зависимости от символа?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Ответ написан
    Комментировать
  • Как понять эту строку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Это тернарный оператор (не страшное слово, просто от числа «3»)

    условие ? выражение1 : выражение2


    Частая ошибка, открыв для себя этот чудесный синтаксис, пихать его везде, где есть условие.
    Но это не замена if .. else, где нужны разные действия.
    Тернарный оператор — для получения значения.
    Ответ написан
    Комментировать
  • Можно ли как-то повесить слушатель на video внутри iframe?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо читать документацию того сервиса с видео.
    Только если они намеренно предусмотрели такую возможность, может получится слушать события.

    В общем случае политика одинакового источника не позволяет обернуть сайт банка в iframe и слушать, какой там пароль вводят в input.
    Ответ написан
    Комментировать
  • Включение и выключение функцыи JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Лучше вместо setInterval() использовать requestAnimationFrame()
    Там принцип: отрисовали кадр – запросили отрисовку следующего. Пошаговая передача эстафеты.

    Завести переменную-флаг, которая будет true или false. Разрешать или запрещать анимацию.

    На каждом шаге смотреть на эту переменную: и делать следующий requestAnimationFrame() только если переменная true.

    Кнопка будет менять состояние этой переменной. И, при переключении из false в true, запускать отрисовку.

    Ещё оптимизация: не нужно в каждом кадре искать элементы, достаточно это сделать один раз.

    Ответ написан
    Комментировать
  • Как найти разность максимального и минимального значения внутри массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Наверное, запутал этот пример с отрицательными:
    console.log(work([-10, -20, -40])); // -40 - (-10) = -30 => 30

    Тут переставили местами зачем-то max и min. Но с отрицательными значениями ничего особенного. Из максимального -10 вычитаем - минимальное -40:
    -10 - (-40) == -10 + 40 == 30
    Никаких if..else, Math.abs() и TensorFlow )

    без reduce и т.д.
    Тогда и без Math.max() / Math.min()

    Один раз пройти по массиву. Сначала и max и min равны первому элементу.
    Когда в массиве всего один элемент, так ведь и будет: он и наибольший и наименьший.

    Идём по элементам массива. Очередной сравниваем с max. Если очередной больше, то обновляем max. Та же логика с min.

    Этот способ и алгоритмически быстрее встроенных Math.max() + Math.min(),
    т.к. решает обе задачи за 1 проход по массиву.
    Ответ написан
    1 комментарий
  • Как облагородить/сократить данный свитч?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Овер-сократить можно примерно так:
    const checkArr = [!mailArr.length, !inputEmptyArr.length];
    if (consentCheckbox) {
      checkArr.push(consentCheckbox.checked);
    }
    btnSubmite.classList.toggle('valid-success', !checkArr.some(x => !x));

    В двух версиях массив отличается наличием последнего элемента .checked
    Разницу - в if()

    every(=== true) логически равноценно !some(=== false) – интересует, есть ли хоть один false.

    Итого всех макарон – добавить или удалить класс.
    Ответ написан
    2 комментария
  • Как разобраться с передачей переменной в параметре функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В нерабочем коде создаётся новый массив – это новая область в памяти, новый объект.
    Переменная entity внутри функции перестала указывать на тот же массив, что и fruits,
    теперь указывает на новый пустой массив.
    подробнее
    function loadEntities(entity, item) {
      // тут entity из аргументов указывает туда же, куда и fruits
      // можно вызывать методы того, внешнего массива, Те же push(), splice()
    
      entity = []
      // а тут entity стала указывать в другую сторону, на новый пустой массив
      // fruits это уже никак не касается
    
      entity.push(item)
      // положили что-то в никчёмный массив
    }


    Вот рабочий вариант. Массив константа. Для его опустошения, длина устанавливается в 0.
    const fruits = []; // навсегда
    
    loadEntities(fruits, 'banana');
    console.log(fruits);
    
    loadEntities(fruits, 'apple');
    console.log(fruits);
    
    function loadEntities(entity, item) {
      entity.length = 0; // массив тот же, но пуст
      entity.push(item);
    }

    Альтернативный способ опустошить массив, сохранив его объект:
    entity.splice(0, entity.length);
    Ответ написан
    1 комментарий
  • Почему не правильно выполняются условия?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    prompt() возвращает текстовую строку.

    Строка "100" меньше (по алфавиту) строки "50".

    Унарный оператор «плюс» сделает из введённой строки число:
    let a = +prompt('Введите 1-е число');

    spoiler
    let a = +prompt('Введите 1-е число');
    let b = +prompt('Введите 2-е число');
    
    if (a < b) {
      [a, b] = [b, a]; // поменяли местами
    }
    // теперь точно a > b
    
    alert(b + ',' + a);
    alert(a + ',' + b);
    Ответ написан
    Комментировать
  • Как удалить текст, не трогая дочерние элементы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо перебирать узлы – Nodes – в свойстве childNodes у label.

    Текст будет в отдельном узле с типом Node.TEXT_NODE и именем nodeName == "#text"

    Методом Node.replaceChild() заменить его на добавляемое под-дерево.

    Ответ написан
    Комментировать