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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно. Курить документацию по localStorage и по Storage
    const dg = document.getElementById.bind(document);
    const inKey = dg('in-key');
    const inVal = dg('in-val');
    dg('btn-to').addEventListener('click', e => {
      localStorage.setItem(inKey.value, inVal.value);
    });
    dg('btn-from').addEventListener('click', e => {
      inVal.value = localStorage.getItem(inKey);
    });
    dg('btn-list').addEventListener('click', e => {
      let list = [];
      for (let i = 0; i < localStorage.length; i++) {
        let k = localStorage.key(i);
        list.push('<dt>'+k+'</dt><dd>'+localStorage.getItem(k)+'</dd>');
        dg('list').innerHTML = list.join('\n');
      }
    });
    рабочий пример
    Ответ написан
    3 комментария
  • Как оптимизировать работу скрипта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо перебирать в цикле имеющиеся значения. Удобнее держать данные (строки) в массиве массивов:
    data = [
        ["M166 E16", "A-Class", "2004", "A 160", "W168.II", "бензин"],
        ["M166 E19", "A-Class", "2004", "A 190", "W168.II", "бензин"],
        // и остальные данные. 
      ];


    Вытащить значения полей ввода лучше лишь 1 раз и запомнить в переменных:
    // вместо многократного
    ($("#class").val())
    // лучше один раз
    var _class = $("#class").val();
    // и потом использовать значение этой переменной


    Общий алгоритм: ищем, перебирая строки. Как только нашли, дальше не ищем. В конце смотрим, нашлось вообще что-то (показываем) или нет (пишем «нет результатов»).

    Поиск вызывает вопросы:
    1. точно ли ищете полное соответствие значений или достаточно подстроки;
    2. важен ли case (может, искать будут «БЕНЗИН» вместо «бензин»
    3. точно ли хотите искать каждое значение во всех полях строки? Например, год – известно же, что он в определённой колонке. Быстрее сравнивать искомый год только с одним полем.


    Сравниние с -1 короче записать так: !!~value – тоже будет false только если value == -1

    Итого
    $(document).ready(function() {
      const data = [
        ["M166 E16", "A-Class", "2004", "A 160", "W168.II", "бензин"],
        ["M166 E19", "A-Class", "2004", "A 190", "W168.II", "бензин"],
        ["M266 E15", "A-Class", "2005", "A 150", "W169.I", "бензин"],
        // и остальные данные. 
      ];
    
    
      $('.left').on('input', function() {
        const _class = $("#class").val(),
          _model = $("#model").val(),
          _god = $("#god").val(),
          _kuzov = $("#kuzov").val(),
          _tip = $("#tip").val()
        ;
        
        var index = -1; // сначала считаем, что "не найдено"
        
        for(let i = 0; i < data.length; i++) {
          let car = data[i];
          if( !!~car.indexOf(_class)
            &&  !!~car.indexOf(_model)
            &&  !!~car.indexOf(_god)
            &&  !!~car.indexOf(_kuzov)
            &&  !!~car.indexOf(_tip)
          ) {
            index = i;
            break;
          }
        }
        
        if(!!~index) {  // нашли и index стал больше -1
          $("#page-title").html( "Мотор " + data[i][0] );
        } else {        // не нашли и index === -1
          $("#page-title").html( "Нет такого" );
        }
      });
    });
    Ответ написан
    Комментировать
  • Где посмотреть структуру современного приложения JS (ES6 модули)?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Ответ написан
    Комментировать
  • Как сделать одновременное редактирование документа, как в google docs?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Почитайте про шаблон проектирования «Команда».

    Понадобится слать из каждого клиента «команды» – каждый введённый символ, удалённый символ, удаление/вставка фрагмента текста, изменение форматирования. И всем редактирующим рассылать каждую полученную команду.

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    попробуйте вместо
    if (document.form.name.value == '' || document.form.phone.value == '' ) {

    вот так:
    if (this.name.value == '' || this.phone.value == '' ) {
    Ответ написан
    Комментировать
  • Как при нажатии на enter добавить?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    При копировании из HTML заменять <br> на \n.
    При копировании из textarea в div – наоборот, \n на <br>:
    document.getElementById("btn-from")
      .addEventListener('click',function(){
        elTa.value = elSrc.innerHTML
          .replace(/<br\/?>/ig, '\n')
          .replace(/\n+/g, '\n')
          .trim()
        ;
    });
    
    document.getElementById("btn-to")
      .addEventListener('click',function(){
        elSrc.innerHTML = elTa.value
          .replace(/\n/g, '<br>')
          .trim()
        ;
    });


    Рабочий пример
    Ответ написан
    Комментировать
  • Как с помощью циклов определить простое или составное число?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Всего два возможных исхода: «простое» или «составное».
    Случай с составным правильно определяется в варианте, где вы поставили break.

    Но там не break нужен. У вас функция, которая должна вернуть значение. Как только обнаружили, что найден делитель, всё, можно сразу возвращать результат «Составное число».

    Я бы порекомендовал такую логику: в цикле только ловите ахтунг-момент найденного делителя - и сразу возвращайте "Составное". Если же весь цикл отработал и не вылетел из функции, возвращайте "Простое". Не надо никаких «флагов» и доп. переменных. Код получается короткий и понятный.

    spoiler
    function testCycle(n) { 
      for (let i = 2; i < n / 2; i++)
        if (n % i === 0)
          return "Составное число"; 
      return "Простое число";
    }

    Примечания:
    • let – это то же, что и var, но действует не в рамках всей функции, а только в рамках блока. В данном случае, внутри цикла.
    • === – это «строгое» равенство. То же, что и ==, но ещё и проверяет, чтобы типы совпадали, т.е. не прокатит "0" === 0. Зато работает чуть быстрее.
    • проверяем не до n, а до n / 2, т. к. целые множители не могут превышать половину произведения (второй множитель не меньше 2)
    Ответ написан
    Комментировать
  • Что делать после todo?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сделайте вложенный todo: где задачи 1-го уровня из себя представляют списки задач.
    Ответ написан
    Комментировать
  • Почему не срабатывает копирование в буфер?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В буфер можно записывать только по действию пользователя: в обработчике клика, например. Но никак не по асинхронному событию где-то в коде.
    You can use the "cut" and "copy" commands without any special permission if you are using them in a short-lived event handler for a user action (for example, a click handler).


    Если у вас код не на странице, а это вы пилите расширение в браузер, можно запросить доп. разрешения, и тогда всё получится.
    Ответ написан
    Комментировать
  • Как после "10" вызовов function write() в сек, блокировать её на "10мин"?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    На стороне сервера – надо сохранять массив времен последних вызовов функции. При очередном вызове смотреть число времен в этом массиве и время самого раннего. Дописывать в конец текущее время и удалять записи старше 1 секунды.

    В качестве хранилища можно использовать Redis или другое хранилище в памяти.

    Если квота распространяется на каждого юзера в отдельности - хранить для каждого отдельно. В качестве ключа использовать в т.ч. user_id.

    На клиенте похожий принцип: хранить массив времен вызовов и проверять число и время самого раннего при каждом.
    Ответ написан
    Комментировать
  • Как разворачивать и сворачивать (2 и более статей не получается)?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Не работает потому, что функцию sh() переопределяете для каждой статьи заново – остаётся последний вариант.

    Лучше сделать так:
    1. Скрываемым частям статей давать класс с display:none У вас это text__podzigilovol.
    2. В ссылке-кнопке для спрятать/показать записывать id управляемой статьи в data-атрибуте: data-id="info-2" – так кнопка будет «знать», кем она управляет.
    3. Кнопкам не писать в href никакого javascript:..., вместо этого лучше на них повесить слушателя события клика. Удобно дать всем кнопкам определённый класс, по нему их отыскать и в цикле повесить слушателя события.
    4. Обработчик клика описывается лишь один раз. Он получает в качестве this кликнутую ссылку. Из неё берёт data-атрибут с id нужного блока. И включает/выключает ему класс, который прячет этот блок.
    Рабочий пример
    Код
    function sh(event) {
      const className = "text__podzigilovol";
      event.preventDefault();
    
      obj = document.getElementById(this.dataset.id);
      if(!obj) return;
      if( obj.classList.contains(className)) {
        obj.classList.remove(className);
      } else {
        obj.classList.add(className);
      } 
    } 
    
    
    Array.prototype.forEach.call(
      document.querySelectorAll('.js-btn-readmore'),
      function(e){
        e.addEventListener('click', sh);
      }
    );
    Ответ написан
    8 комментариев
  • Из строки с "часами", сделать таймер?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    «Закидывайте» и «ловите» не сколько осталось, а время того события, до которого отсчитываете. В виде Unix timestamp'а, целого числа. Так всегда сможете посчитать, сколько осталось.
    Ответ написан
    Комментировать
  • Как заменить элементы одного массива элементами другого по заданному правилу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Забыли .length – вероятно, собирались перебирать i от 0 до длины строки arr1. Тут не массивы, а две строки.

    for (i=0; i<arr1.length; i++) {
        for (j=0; j<arr2.length; j++){


    Вложенный цикл не нужен. Достаточно перебрать каждую цифру входа.

    Чтобы найти соответствующую цифре i букву, достаточно взять i-й элемент строки arr2:
    arr2[ i ];

    Коротко, в одну строку это можно решить через преобразование строки в массив и применение функции к каждому элементу.
    В одну строку
    var arr1 = '3649824598';
    var arr2 ='АБВГДЕЖЗИК';
    
    arr1.split('').map(n => arr2[n]).join('')  // ГЖДКИВДЕКИ

    • split('') сделает из строки массив цифр;
    • map() применит к каждой цифре функцию, которая заменит цифру на соотв. букву из arr2;
    • join('') склеит элементы массива (теперь уже буквы) в одну строку.
    Ответ написан
    Комментировать
  • Использование web workers?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Объекты в web worker передаются через сериализацию "structured clone algorithm" и есть ограничения. Нельзя передать функцию и, соотв., логику.

    С другой стороны, можно создавать worker динамически, из data-url, как это описано тут:
    <script type="text/js-worker">
      var myVar = 'Hello World!';
      // остальной код web-worker'а
    </script>
    <!-- ... -->
    <script type="text/javascript">
      var blob = new Blob(Array.prototype.map.call(document.querySelectorAll('script[type=\'text\/js-worker\']'), function (oScript) { return oScript.textContent; }),{type: 'text/javascript'});
    
      // Creating a new document.worker property containing all our "text/js-worker" scripts.
      document.worker = new Worker(window.URL.createObjectURL(blob));

    Полный код примера см. по ссылке выше.

    Т.е. можно хоть в JS на странице сгенерировать код для worker'а и запустить рабочего.
    Ответ написан
    2 комментария
  • Как отложить выполнение jQuery кода до загрузки библиотеки jQuery?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    <script>
      window.onload = function(){
        // ваш script использующий jQuery
      }
    </script>
    
    ...
    
    <!-- загрузка библиотеки jQuery -->
    <script src="https://yastatic.net/jquery/3.1.1/jquery.min.js"></script>
    Ответ написан
    2 комментария
  • Как переписать функцию на современный лад?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В таком виде, как написали, можно просто
    (() => {
      a();
      b();
      c();
    })()
    Ответ написан
    Комментировать
  • Как запустить AJAX в цикле?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    function poll() {
      $.post("https://vash.api.com", {name: "Aladdin", id: "001"}, function(response) {
        if( response.ok === 'OK') { // получен нужный ответ
          window.location.reload(true);
        } else {
          setTimeout(poll, 8000);
        }
      });
    }
    
    poll();
    Ответ написан
    Комментировать
  • В Javascript оператор var действует на одну или на несколько переменных?

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var money = 0; // есть переменная money и ее значение 0
    
    function getRich() {
      money = money + 1;
    }
    
    // теперь в любой момент можно разбогатеть:
    getRich();
    getRich();
    getRich();
    // ура! денег стало больше:
    // в переменной money лежит число 3
    Ответ написан
    2 комментария
  • Почему говорят что forEach меняет начальный массив, если он ничего не меняет?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В вашем примере, где массив содержит элементы примтивного типа Number, в функцию передаётся значение. Изменение внутри функции не распространяется на изменение в массиве.

    Если бы в функцию передавались объекты, передача была бы «по ссылке» и изменения в эти объекты отразились бы сразу в массиве.

    В вашем примере можно задействовать два других параметра: индекс элемента и сам массив и явно поменять элементы массива:
    arr = [1,2,3]
    arr.forEach((a,i, theArr) => {
      a = a + 1 ;
      theArr[i] = a;
    })
    console.log(arr) // [2,3,4]

    Поробнее про передачу by value / by reference на англ. на SO. Пример оттуда:
    function changeStuff(a, b, c)
    {
      a = a * 10;
      b.item = "changed";
      c = {item: "changed"};
    }
    
    var num = 10;
    var obj1 = {item: "unchanged"};
    var obj2 = {item: "unchanged"};
    
    changeStuff(num, obj1, obj2);
    
    console.log(num);        // 10
    console.log(obj1.item);  // changed   
    console.log(obj2.item);  // unchanged
    Ответ написан
    Комментировать