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

    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 бы не было.
    Ответ написан
    Комментировать
  • Почему у задачи такое решение?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    А как вы код написали, если не можете понять, как он работает?

    Вы открывали документацию функции, читали, что она делает и какие аргументы принимает?
    Ну, давайте я вам её сюда скопирую:
    Parameters
    indexStart
    The index of the first character to include in the returned substring.
    indexEnd Optional
    The index of the first character to exclude from the returned substring.
    Description
    If indexStart < 0, the index is counted from the end of the string. More formally, in this case, the substring starts at max(indexStart + str.length, 0).
    If indexEnd < 0, the index is counted from the end of the string. More formally, in this case, the substring ends at max(indexEnd + str.length, 0).


    зачем нужен (-2, -1)
    Для выполнения вот этого условия задачи: "если слово заканчивается на мягкий знак, то получите предпоследнюю букву". Я искренне не понимаю, что тут можно добавить...
    Ответ написан
  • Как исправить проблему с асинхроностью?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Ошибка первая: вы в sliceHandler передаёте div-обёртку, а внутри функции думаете, что это какой-то его ребёнок.
    Ошибка вторая: вы пытаетесь получить реактовское служебное свойство key через атрибут html-тега. Значение key даже через props нельзя получить, не говоря уже про html.

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

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    А что, стрелочные функции не принимают аргументов или не возвращают результат? Или делают это как-то иначе? Или они не являются функциями?
    Вопросы риторические.

    "Говорите" про них ровно так же, как про обычные. Когда окажется важным, что это именно стрелочная функция (а это бывает довольно редко), так и уточняйте.
    Ответ написан
    3 комментария
  • Как перезагружать страницу при появлении определённого элемента?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Самое простое и надёжное - проверять наличие элемента каждые N секунд (например, 5):
    setInterval(function () {
      const $element = document.querySelector("#content > div > div.taskblackout");
    
      if ($element && $element.style.display === 'block') {
        document.location.reload()
      }
    }, 5000);

    Единственный минус этого решения - задержка. Элемент может появиться сразу после срабатывания и провисит эти N секунд.
    Ещё, если вы часто уходите с этой вкладки, может накопиться очередь из интервалов - в этом случае лучше заменить на setTimeout, который внутри будет вызывать следующий setTimeout:
    const check = () => {
      const $element = document.querySelector("#content > div > div.taskblackout");
    
      if ($element && $element.style.display === 'block') {
        document.location.reload()
      } else {
        setTimeout(check, 5000);
      }
    };
    
    setTimeout(check, 5000);
    Ответ написан
    1 комментарий