Ответы пользователя по тегу JavaScript
  • Как сохранить состояния select, checkbox, radiobuttons и пр. на странице HTML?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Не совсем понятно, что именно вам нужно сохранять и что именно не работает.
    Временное состояние формы, чтобы пользователь мог закрыть страницу, не отправляя изменения на сервер, и вернуться к ней позже? Или прям полноценное редактирование?

    Если второе, то это и должно храниться на сервере. Или у вас при открытии формы поля формы не заполняются значениями из БД и она пуста? Тогда это отдельная проблема, не имеющая никакого отношения к JS.

    Если же первое, то у вас, как я понял, уже есть какой-то скрипт, только он багованный - показывайте, мы вам поможем разобраться.
    Ответ написан
  • Динамическое создание тега на JS, почему не сработает обработчик событий?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Ведь мы создаем новый li при клике на btn, и он попадает в DOM
    Ну да, попадает. А чтобы что-то с ним делать, нужно навесить обработчик события. Совершенно непонятно, что вас в этом процессе удивляет.
    Вы можете делегировать обработку события родительскому контейнеру (<ol />) и тогда навешивать отдельные обработчики на создаваемые элементы не придётся.
    Ответ написан
    3 комментария
  • Ререндеринг при использовании setError?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Скорее всего, ваша проблема находится здесь:
    if (files[0].size > 150) {
        setError('file', { type: 'custom', message: 'Недопустимый размер' });
    }
    ...
    setStep(2)

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

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    1. Получаем все нужные td, используя querySelectorAll.
    2. Получаем для каждой ячейки значение (видимо, из инпута?).
    3. Приводим значение к числу.
    4. Прибавляем получившееся число к сумме.


    Какой конкретно из этих элементарных пунктов вызывает у вас сложности? В чём эти сложности заключаются? Какой код у вас получился на данный момент?
    Ответ написан
    6 комментариев
  • Ошибка записи результата в переменную?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Ответ написан
    Комментировать
  • Как добавить строку в текстовый инпут из коллекции элементов или массива по событию?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    - indexToHeaderList = String(headerArr[choosenElem]);
    + indexToHeaderList = headerArr[choosenElem].innerText;

    Возможно, вместо innerText вам больше подойдёт textContent (но вряд ли).

    оператором typeof - пишет что это строка
    Ну так вы же по-любому на typeof проверяли после того как сами руками к строке привели?
    Ответ написан
    2 комментария
  • Как перезапустить функцию в случае ошибки?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Какого-то стандартного универсального retry у промисов, вроде, нет.
    Поэтому можно использовать что-то подобное:
    let runWithRetry = async (func, tries = 5) => {
        let attempt = 1;
        while (attempt <= tries) {
            try {
                return await func();
            } catch (error) {
                console.log(`Attempt #${attempt} failed: ${error}`);
                attempt++;
            }
        }
    
        throw new Error(`Failed after ${tries} tries`);
    };
    
    try {
        let busyWork = () => new Promise((resolve, reject) => {
            setTimeout(() => (Math.random() > 0.75 ? resolve(Math.random()) : reject()), 1000);
        });
    
        let result = await runWithRetry(busyWork, 5);
    
        console.log(result);
    } catch (error) {
        console.error(error);
    }
    Ответ написан
    Комментировать
  • Странные запросы на сервер. Они представляют опасность?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    смогут ли они таким макаром выполнить все эти команды?
    Если у вас какая-нибудь дыра, которую они эксплуатируют, открыта, то смогут. Но вероятность этого не очень велика. Обновляйтесь вовремя и следуйте основным инструкциям по безопасности для ваших инструментов.
    Ответ написан
    Комментировать
  • Как оставить focus рабочим только для меню?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега CSS
    Нужно назначать кликнутой ссылке отдельный класс, который бы обозначал её активность.
    Это делает на основании адреса страницы либо бэкенд при генерации шаблона, либо JS, если это SPA.

    В представленной песочнице это может выглядеть примерно так:
    .nav ul li a.active {
      text-decoration: underline;
      text-decoration-thickness: 2px;
      text-underline-offset: .1em;
    }

    const $links = document.querySelectorAll('.nav a');
    
    Array.from($links).forEach(($link) => {
      $link.addEventListener('click', (event) => {
        document.querySelector('.nav a.active')?.classList.remove('active');
        event.target.classList.add('active');
      })
    });
    Ответ написан
    1 комментарий
  • Как получить Get запрос?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    history.pushState({}, '', '/www?' + $(this).serialize());
    https://developer.mozilla.org/en-US/docs/Web/API/H...
    Ответ написан
    Комментировать
  • Сравнить элементы массива js и отфильтровать если будет более 3-х дублей одного элемента?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Представим, что нам нужно реализовать самый замороченный вариант: важны типы данных, порядок элементов должен сохраняться, а код должен быть понятным.
    Выкидываем значение полностью

    Исправленный код из вопроса:
    let arr = [1, true, 1, 'null', 1, '2', '1', true, 1, true, 'null', true, 'null'];
    let res = arr.filter((el) => arr.filter((i) => i === el).length <= 3);
    
    console.log(res); // ['null', '2', '1', 'null', 'null']


    Или мой чуть более упоротый вариант:
    function solution(input, threshold = 3) {
        let counter = new Map();
    
        input.forEach((item) => {
            let prevCount = counter.get(item) || 0;
    
            counter.set(item, prevCount + 1);
        })
    
        let valid = [];
    
        counter.entries().forEach(([item, count]) => {
            if (count <= threshold) {
                valid.push(item);
            }
        });
    
        return input.filter((item) => valid.includes(item));
    }
    
    let arr = [1, true, 1, 'null', 1, '2', '1', true, 1, true, 'null', true, 'null'];
    console.log(solution(arr)); // ['null', '2', '1', 'null', 'null']


    Оставляем только первые N значений
    function solution(input, threshold = 3) {
        let result = [];
        
        let counter = new Map();
    
        input.forEach((item) => {
            let prevCount = counter.get(item) || 0;
            let count = prevCount + 1;
    
            counter.set(item, count);
    
            if (count <= threshold) {
                result.push(item);
            }
        })
    
        return result;
    }
    
    let arr = [1, true, 1, 'null', 1, '2', '1', true, 1, true, 'null', true, 'null'];
    console.log(solution(arr)); // [1, true, 1, 'null', 1, '2', '1', true, true, 'null', 'null']
    Ответ написан
  • Как работают фигурные скобки в javascript?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Высокоуровневое описание, в котором есть ссылка на спецификацию для изучения деталей:
    https://developer.mozilla.org/en-US/docs/Web/JavaS...

    И ещё полезно прочитать про лексическое оружие: https://learn.javascript.ru/closure#leksicheskoe-o...
    Ответ написан
    1 комментарий
  • Как решить ошибку Uncaught TypeError: Cannot read properties of null (reading 'insertAdjacentHTML')?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    document.getElementById('9') возвращает null, нет на странице такого элемента. Почему его нет, по приведённому коду сказать невозможно.

    Ломать себе голову тут не над чем и вариант решения только один - он легко находится по тексту ошибки.

    Числовой ID - это вообще плохая идея и раньше так было нельзя.
    Сейчас можно, но ломается древняя магия:
    662ced4e6486b726512210.png
    Ответ написан
    Комментировать
  • Запись в cookie или localStorage только при открытии страницы?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Определите для себя критерии "зашёл на сайт" и используйте их.
    Но ничего лучше, чем "перестаём засчитывать заход на N минут после регистрации" придумать (и уж тем более реализовать), скорее всего, не выйдет.

    Отделить само по себе открытие страницы от обновления нельзя, но можно смотреть в document.referrer - если там ваш сайт, то это обновление. Однако, это не слишком надёжное поле. Нет, document.referrer по F5 не меняется.
    Ответ написан
    Комментировать
  • Как следить за всей страницей разом через IntersectionObserver?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    IntersectionObserver нужен, чтобы следить за тем, что какой-то конкретный элемент пересёкся с каким-то другим элементом или видимой областью экрана. Соответственно, потребность следить за "всей страницей" - это нечто странное и это невозможно. Все элементы всегда пересекаются с body и body всегда пересекается с вьюпортом.
    Ответ написан
    2 комментария
  • Почему в консоль выводятся элементы, которые ещё не добавлены?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Браузерная консоль показывает содержимое объектов в том виде, в котором они находятся в данный момент, а не в момент логирования - такая вот у неё особенность в целях экономии памяти. Обратите внимание, что на вашем скриншоте изначально написано, что в массиве два элемента, как это было на момент логирования, а вот при разворачивании показывается уже текущее состояние.
    Чтобы этого избежать, приходится делать так:
    console.log({...names});

    Но, если в объекте находятся другие объекты (как у вас) и они изменяются тоже, то простое копирование не поможет.
    Поэтому используют вот такую конструкцию:
    console.log(JSON.parse(JSON.stringify(data)));
    Есть и другие способы сделать глубокую копию объекта, но я для этих целей предпочитаю такой.
    6616669cb48f8316007497.png
    Ответ написан
    6 комментариев
  • Как на BeforeUnload выполнить действие?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Это делается не так. При смене таба вам просто нужно добавлять запись в History API и всё будет работать так, как вы хотите, автоматически.
    Событием beforeunload злоупотребляют спамеры, поэтому полагаться на него не стоит (не говоря о том, что это костыль).
    Ответ написан
    5 комментариев
  • Как добавить элементу стили из объекта?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Даю удочку, не рыбу. Тут три составляющих:
    • Итерация по ключам-значениям объекта. Способов несколько, все описаны на первых страницах любого учебника.
    • Сохранение значения конкретного стиля. Тоже элементарно: element.style.backgroundColor = value.
    • Использование переменной в качестве названия свойства. Тоже на первых страницах учебника.

    Но перед этим нужно раз и навсегда уяснить разницу между массивом и объектом в js и использовать корректные термины.
    Ответ написан
    3 комментария
  • Как работает then в промисах?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Здесь можно даже и не заподозрить, что then что-то возвращает.
    Все функции в js что-то возвращают. Если явного return нет или в нём не указано значение, то возвращается undefined.

    Но поскольку там null, можно подумать, что исходный промис просто как-то передается дальше.
    Так и есть - вы не передали никакой callback и весь этот вызов как бы игнорируется. Этот сценарий аналогичен предыдущему.

    Еще интереснее - then возвращает простое значение, которое моментально попадает в следующий then.
    Это ваш callback возвращает простое значение, которое then оборачивает в отрезолвленный промис.

    Можете рассказать в общих чертах, если then возвращает промис, то как он его формирует?
    Ну берёт и формирует... Примерно так:
    then = (onFulfilledCallback, onRejectedCallback) => {
      try {
        let newValue;
    
        if (this.previousValue instanceof Error) {
          newValue = onRejectedCallback(this.previousValue);
        } else {
          newValue = onFulfilledCallback(this.previousValue);
        }
    
        if (newValue instanceof Promise) {
          return newValue;
        } else {
          return Promise.resolve(newValue);
        }
      } catch (error) {
        return Promise.reject(error);    
      }
    }
    Это псеводокод но общий смысл такой.
    Ответ написан
    5 комментариев
  • Почему return не возвращает значение?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    let makeItDouble = (text) => {
      let i = text + text;
      return i;
    };
    
    console.log(makeItDouble("I never look back"));
    Return всё прекрасно возвращает. Но то, что он возвращает, нужно сохранять в переменную или использовать сразу. Переменная i находится внутри функции и снаружи недоступна. Если бы можно было делать так, как вы написали, то и смысла в return бы не было.
    Ответ написан
    Комментировать