Задать вопрос
Ответы пользователя по тегу JavaScript
  • Можно ли отсрочить запрос на сервер?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Мало подробностей реализации.

    Как рендерит мой хрустальный шар: есть какой-то контейнер <div> в который засовываются картинки. И полученные с сервера и добавленные пользователем.

    Почему бы не вставлять их туда разными методами. Полученные с сервера в конец appendChild(), добавленные пользователем в начало prepend()
    Серверный метод сохранения пусть записывает добавленные картинки в начало.

    Или, более «правильно», держать все картинки в массиве. При изменении массива перерисовывать весь div. Добавленные картинки unShift(), полученные с сервера push(). Для сохранения на сервер отправлять весь массив.
    Ответ написан
    Комментировать
  • Вопрос про LocalStorage, почему?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    setCartData();

    похоже, корзинку-то забыли. Сохраняется пустота.
    spoiler
    наверное, надо так:setCartData(pay);
    Ответ написан
    1 комментарий
  • Как выполнить проверку на то, что был ли у пользователя отключен localStorage?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    MDN рекомендует такую функцию:
    function storageAvailable(type) {
        var storage;
        try {
            storage = window[type];
            var x = '__storage_test__';
            storage.setItem(x, x);
            storage.removeItem(x);
            return true;
        }
        catch(e) {
            return e instanceof DOMException && (
                // everything except Firefox
                e.code === 22 ||
                // Firefox
                e.code === 1014 ||
                // test name field too, because code might not be present
                // everything except Firefox
                e.name === 'QuotaExceededError' ||
                // Firefox
                e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
                // acknowledge QuotaExceededError only if there's something already stored
                (storage && storage.length !== 0);
        }
    }


    Применение:
    if (storageAvailable('localStorage')) {
      // Yippee! We can use localStorage awesomeness
    }
    else {
      // Too bad, no localStorage for us
    }
    Ответ написан
    Комментировать
  • Как показать последние 4 символа в строке, а остальные заменять?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Может, без регулярок?
    const mask = (s) => '*'.repeat(s.length - 4) + s.substr(-4);
    
    mask('1234567890123456') // "************3456"
    Ответ написан
    Комментировать
  • Защита от автоматизации?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    возможно, проверяют свойство события isTrusted. Чтобы его подделать, наверное, нужна автоматизация «над» браузером.
    Ответ написан
  • Как показать и запустить таймер по клику?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. Клик по кнопке определяет дату-время «сейчас», добавляет к ней 45 минут и сохраняет значение в localStorage.
    const timerKey = 'myTimer';
    function onButtonClick() {
      const D = new Date();
      D.setTime(45 * 6e4 + D.getTime()); // добавить 45 минут
      localStorage.setItem(timerKey, D.getTime()); // сохранить на случай обновления страницы
      startTimer(D.getTime()); // показывать обратный отсчёт
    }
    
    document.getElementById("id1").addEventListener("click", onButtonClick);

    2. обратный отсчёт отображает разницу текущего времени и «времени Че»
    function startTimer(ts) {
      function showTime() {
        const till = Math.max(0, che - Date.now()); // не меньше 0
        // далее вывод этого времени в нужном месте
        let seconds = Math.floor(till / 1000);
        const hours = Math.floor(seconds / 3600);
        seconds -= hours * 3600;
        // ...
    
        if (till > 0) setTimeout(showTime, 200);
      }
    
      const che = +ts; // чтобы число
      showTime();

    3. при загрузке страницы смотреть, если ли что в localStorage и запускать таймер, если есть
    const savedChe = +localStorage.getItem(timerKey);
    if (savedChe) startTimer(savedChe);
    Ответ написан
    4 комментария
  • Как можно заново загрузить javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Есть скрипт который нужно после события click загружать заново.

    Здесь что-то очень, очень неправильно.

    Скрипт загружается единственный раз и сохраняется в кэше браузера. Выполнять его можно многократно.

    Хорошо бы привести содержание скрипта в вопросе. Под «спойлером», если он длинный. Обязательно обернув в тег <code>.

    Можно обернуть код файла в функцию. И вызывать её сразу при загрузке скриптов. И потом по клику.

    Например, в загружаемом скрипте было так:
    my_script.js
    var message = "Привет Хабр";
    alert(message);
    А вы сделайте так:
    my_script.js
    function my_func() {
      var message = "Привет Хабр";
      alert(message);
    }
    и в коде страницы:
    <button id="btn">нажми</button>
    
    <script src="my_script.js"></script>
    <script>
    document.addEvenListener('load', my_func); // при загрузке страницы выполнить
    document.getElementById('btn').addEventListener('click', my_func); // и при нажатии кнопки
    </script>
    Ответ написан
    2 комментария
  • Отображение в html содержимого формируемого в javascript, это возможно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    роботы разберутся и без оглавления, которое не несёт в себе ничего нового.
    Ответ написан
    Комментировать
  • Как сократить оператор if в JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    if (a == 1 && a == 2)

    (почти) всегда будет false, т.к. не может быть одновременно равно и 1 и 2 (может последовательно), так что смело удаляйте весь блок.

    Если интересует «если а равно одному из списка», можно так:
    if ([1, 2, 100500].includes(a))
    Ответ написан
    1 комментарий
  • Почему не работает setTimeout?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    setTimeout(function () {
      var counter = 0;
    
      setTimeout(() => counter++, 1000); // через 1с увеличит на 1
    
      console.log(counter); // выведет 0, сразу
    
      setTimeout(() => {
        console.log(counter);
        nextselect.addClass('same-as-selected').trigger("click");
      }, 1400); // через 1.4с "кликнет"
    }, 500); // вообще всё начнётся только через пол-секунды
    
    
    0         - начало
    0.5       - начнёт выполняться внешняя ф-я:
                зарядятся два таймера, в промежутке выведет 0
    0.5 + 1   - counter увеличится на 1
    0.5 + 1.4 - еще раз выведется counter, добавится класс, клик
    Ответ написан
    2 комментария
  • В чем ошибка в цикле вывода четных чисел?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. for (let i = 0; i < 50; ...
      от 0 и до, но не включая, 50. Поменяйте 0 и < 50, чтобы это исправить.
    2. out += i + ' ';  // добавляется всегда, в любом случае
      if ( i % 2 != 0) continue; // проверка уже потом
      поменяйте порядок: сначала проверка, потом добавление
    3. document.querySelector('.out-2').innerHTML = out;
      срабатывает в каждой итерации цикла. А надо 1 раз, когда цикл отыграл все повторы. Вынесите эту строку из цикла.


    spoiler

    2..50 через один, по чётным — это 2 * (1..25) подряд.
    document.querySelector('.b-2').addEventListener('click', () => {
      document.querySelector('.out-2').innerText = Array(25) // создали массив из 25 пустых слотов
        .fill() // заполнили их undefined, чтобы можно было..
        .map((n, i) => 2 * (i + 1)) // каждый заменить на (его индекс + 1) * 2
        .join(' '); // и склеить в строку через пробел
    })
    все эти методы массива можно посмотреть на MDN.


    Ответ написан
    1 комментарий
  • Как создать функцию/переменную с проверкой, что они еще не созданы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    чтобы не раздувать файл, решил вынести общие функции и переменные в отдельный файл

    Ну вот практически уже используете модули, но ещё не совсем. Раз там какие-то переменные хранятся, значит для каждого калькулятора, видимо, нужна своя _копия_ этого общего куска.

    Как вариант, оберните всё, что там общего, в класс или функцию или объект и создавайте для каждого калькулятора новую копию.

    calc_init.js?1 не удачная идея. Именно потому, что возникают описанные в вопросе проблемы.
    Лучше один раз его просто загрузить <script src="calc_init.js"></script>. Пусть там просто определяется единственная
    функция
    function calc_init(n, id) {
      let el_script = document.createElement("script");
      el_script.src = `/scripts/script_${n}.js`;
      el_script.setAttribute('defer', '');
      document.body.appendChild(el_script);
    
      let el_div = document.createElement("div");
      el_div.setAttribute('id', id);
      document.body.appendChild(el_div);
    }
    и потом вызывать его функцию:
    calc_init(1, 'id_calc_1'); // номер калькулятора и id HTML-элемента, куда его впихнуть
    calc_init(3, 'id_calc_3');
    Ответ написан
  • Как сложить числа из 2 функций?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Продумайте, в какой момент что происходит. Какие есть события.

    Из каждой функции обновляйте значение переменной и отображайте сумму переменных:
    var price_pech = 0;
    var price_idosn = 0;
    
    //... 
    function MyFunction(sum) {
      price_pech = sum;
      $("#total_price").text(price_pech + price_idosn);
    }
    Ответ написан
    4 комментария
  • Как отследить событие работающего таймера?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    в clearText() выполнять timer.innerHTML = 0;

    Вообще не айс держать в разметке значения. Лучше в какой-то переменной хранить число, и по таймеру его отображать в div:

    Таймеры в JS далеко не идеально точны. Если вкладка браузера перестаёт быть активной, таймеры в ней станут реже тикать. Поэтому не считайте setInterval(func, 1000) идеальной секундной стрелкой.

    Если важна точность, лучше запоминать момент времени const D = new Date(); и по таймеру брать текущее время и считать разницу с тем моментом: let seconds = Math.round((new Date() - D) / 1000)

    Событие таймера при этом можно вызывать чаще, чем раз в секунду: скажем, раз в 200 мс.
    Ответ написан
    Комментировать
  • Как сделать поиск нескольких div с id через textarea?

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

    id через пробел или запятую.
    $('#search').on('input', function(){ // При вводе текста..
      $('.table-item.-active').removeClass('-active'); // убираем класс .-active у .block.-active
      const ids = $(this).val().split(/[ ,]/).filter(el => el.length);
      for (let id of ids) {
    	  $(`.table-item[id="${id}"]`) // берём блок у которого есть совпадение по id
          .addClass('-active'); // выдаём ему класс .-active
      }
    });
    Ответ написан
    2 комментария
  • Как в js указать все числа находящиеся в определенном диапазоне?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В JS есть клевая штука: генераторы.
    Чтобы не забивать сразу память всеми значениями (что, если понадобится от 1 до 1050), можно их получать по одному:
    // эта функция - Генератор. Он создаёт итерируемые штуки
    function* makeRangeIterator(start = 0, end = 100, step = 1) {
        let iterationCount = 0;
        for (let i = start; i < end; i += step) {
            iterationCount++;
            yield i;
        }
        return iterationCount;
    }
    
    // вот сделаем итератор от 1 и до 10 (исключая конец)
    var r1_10 = makeRangeIterator(1, 10);
    
    // в цикле получим из итератора значения
    for (i of r1_10) {
      console.log(i); // выведет от 1 до 9
    }
    Ответ написан
    Комментировать
  • Почему не срабатывает условие (подсчет слов в тексте)?

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

    Логика вашего скрипта: разбить текст по пробелу ИЛИ запятой ИЛИ точке. Регулярка для этого - группа символов в квадратных скобках: /[ ,.]/ — будет соответствовать пробелу или запятой или точке.

    Подвох в том, что могут получаться пустые строки как элементы массива. Например, из "test one." получится ["test", "one", ""] Поэтому стоит пройтись по массиву, оставив в нём только строки ненулевой длины: arr.filter(w => w.length > 0)

    Ну и взять длину полученного массива.
    Ответ написан
    Комментировать
  • Влияет ли цикл requestAnimationFrame на скорость воспроизведения анимации?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    разная частота вызовов функции в requestAnimationFrame() – зависит от устройства, активности/неактивности вкладки и др.

    Но в вашу функцию параметром при вызове передаётся время, прошедшее с некого момента старта, первого вызова. И положение куба стоит расчитывать исходя не из числа вызовов функции, а только исходя из времени.

    Так анимация в разных условиях будет иметь идентичную скорость перемещения куба, хоть и с разной частотой кадров: где-то плавнее, где-то скачками, но, например, коснётся пола он одновременно на всех устройствах.
    Ответ написан
    Комментировать
  • Как ускорить while loop?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    includes() и indexOf() каждый раз, считайте, пробегают, в среднем, по полстроки.
    Представьте, что там дико длинные строки, гигабайтные.
    Поэтому алгоритм желательно построить так, чтобы по каждой Войне и Миру пройтись 1 раз или меньше.

    Условие хорошо сужает возможные символы до всего 26 букв латинского алфавита a..z

    Рабочее решение под
    спойлером

    Например, можно создать массив из 26 счётчиков и заполнять их из первой строки и опустошать из второй.
    Вот такое моё решение прошло тест:
    function scramble(str1, str2) {
      if (str1.length < str2.length) return false;
      const a = Array(26).fill(0);
      for (let c of str1) a[c.charCodeAt(0) - 97]++;
      for (let c of str2) a[c.charCodeAt(0) - 97]--;
      for (let n of a) if (n < 0) return false;
      return true;
    }
    * 97 это ASCII-код маленькой латинской "a"
    Ответ написан
    Комментировать
  • Как записать в одномерный массив все элементы из многомерного?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Ошибка в том, что возвращается всегда массив.
    В т.ч. там, где вроде бы хотели массив распаковать.
    Ответ написан
    Комментировать