Ответы пользователя по тегу JavaScript
  • Как удалить элемент массива в localstorage, по нажатию на крестик, и перезаписать массив?

    @alexalexes
    Нужно использовать обертку+замыкание для обработчика, удаляющего элемент по клику.
    tasks.push(data); // тут вставили очередной элемент
    let task_index = tasks.length - 1; // узнаем его индекс по длине массива, так как он в текущей ситуации последний
    // несколько строк спустя
    b1.addEventListener("click", 
    (function(inner_task_index) // функция-обертка для изоляции контекста, сюда передается значение task_index, я специально выделил его другим именем inner_task_index, чтобы видеть контекст функции-обертки
      {
    // обертка возвращает функцию-обработчик события  для addEventListener
    return function delFromLocalSt() {
        task.removeChild(li);
            let array = JSON.parse(localStorage.getItem('task'));
            array.splice(inner_task_index, 1); // удаляем элемент по известному индексу используя механизм замыкания, используя контекст функции обертки
        localStorage.setItem('task', JSON.stringify(array));
       }
    })(task_index) // вызываем хитрую обертку, чтобы обеспечить изоляцию переменной от контекста функции createEl
    );
    Ответ написан
    1 комментарий
  • Где в Chrome, нужно смотреть JS-события, применённые к элементу во время какого-либо действия с этим элементом?

    @alexalexes
    F12. Раздел "Элементы", выбираете элемент, на котором нужно посмотреть обработчик события. В области интерфейса для просмотра свойств элемента выбираете вкладку "Прослушиватели событий". Выбираете вид события, и выбираете точку входа в JS коде на это событие. Далее, при просмотре кода JS на вкладке "Источники" выбираете, где вам поставить точки останова, чтобы словить остановку выполнения обработки события.
    PS: Такой метод исследования работает только на ванильном или слабо прототипированном коде, написанный без применения библиотек и фреймворков. При использовании библиотек и фреймворков точки привязки событий будут указывать, как правило, на одну единственную функцию в этой библиотеке, отвечающей за высокоуровневый байндинг событий. В этом случае нужно изучать, какие инструменты для отладки есть в самой библиотеке или фреймворке.
    Ответ написан
    Комментировать
  • Как записать выбранное значение в скрытый инпут?

    @alexalexes
    С практической точки зрения целесообразно использовать не текстовое значение label, а для каждого элемента input[type="radio"] снабдить своим value. Установленное value от радиокнопки легче получать и потом как-то использовать.
    Но если хочется с текстовыми пунктами играться, то можно их вычленить так:
    $("input[name='block1']").on('change', function() 
    {
      let current_label = this.parentNode.querySelector('label'); // от кликнутого элемента this получаем родителя, в родителе ищем первый попавшийся label - предположительно он содержит, то что нужно. 
      $("input[name='block1_check']").val(current_label.innerText); // вставляем в нужный скрытый инпут содержимое label
    })
    Ответ написан
  • Как исправить ошибку закрытия таба при попытки ввода информации в input?

    @alexalexes
    На элемент inputa type="number" повесить обработчик события клика с вызовом остановки всплытия события.
    PS: Ссылка для получения полного понимания механизма всплытия/погружения событий.
    Ответ написан
    Комментировать
  • Как изменить высоту срабатывания скрипта?

    @alexalexes
    Прибавьте или убавьте к одному из этих операндов.
    pageYOffset < document.documentElement.clientHeight
    Ответ написан
    Комментировать
  • Как обратиться к id элемента в коллекции?

    @alexalexes
    У вас уже есть коллекция элементов. Зачем вам еще работать с id, если вы их не знаете?
    Просто пробегаетесь по коллекции и что-то там делаете с содержимым каждого элемента, это сразу отразится на DOM (если, конечно, при получении коллекции вы не клонировали элементы).
    let elem_count = elems.length;
    for(let i = 0; i < elem_count; i++)
    {
      let elem = elems[i];
      // что-то сделать с elem
    }
    Ответ написан
  • Как вызывать событие при клике на дочерний элемент?

    @alexalexes
    Если стоит цель обработать клик на конкретном элементе или на его контейнере, то повешайте обработчик на один из этих элементов, а не на весь документ, иначе замучаетесь идентифицировать target.
    let elem = document.querySelector('.elem'); // Берем нужный контейнер
        elem.addEventListener('click' , function(e) // вешаем обработчик только на elem, за счет всплытия события, обработчик будет срабатывать на всех дочерних элементах
        {
          alert('k');
        });

    Если уж хотите оставить обработчик на документе, то идентифицируйте target.
    document.addEventListener('click' , function(e)
        {
          let elem = document.querySelector('.elem');
          if(   e.target == elem // кликнули на сам контейнер elem
             || e.target.tagName == 'SPAN' && e.target.parentNode == elem // или кликнули на какой-то элемент span, непосредственный родитель которого есть наш контейнер elem
            )
          {
            alert('k');
          }
        })
    Ответ написан
  • Что значит и как работает аргумент e в данном коде?

    @alexalexes
    У второго параметра replace, когда он используется в качестве функции есть в документации раздел по этому поводу.
    В параметр e передается результат работы регулярки.
    То же самое, что дает метод match применительно к строке.
    Ответ написан
    1 комментарий
  • Как перебирать массивы, которые находятся внутри других массивов?

    @alexalexes
    Итераторов for/foreach в JS вагон и маленькая тележка. Выбирайте, что по душе.
    Самое простое, что можно применить:
    for( let post of _data)
    {
      let body = post.body;
      // что-то сделать с body
      for(let block of body.blocks)
      {
        // что-то сделать с block
        for(let curr_data of block.data)
        {
         // что-то сделать с data в block
        }
        // что-то сделать с block
      }
      // что-то сделать с body
    }
    Ответ написан
    3 комментария
  • Как в javascript classe запустить метод в другом методе?

    @alexalexes
    Проблема классическая в отношениях разработчика и JS - смена контекста объекта класса от места вызова.
    Чтобы заставить JS использовать только контекст объекта, нужно использовать стрелочный синтаксис для методов:
    class DeviceController {
      getItems = async (query)  => {
            let { brandId, typeId, limit, page, } = req.query
            page = page || 1
            limit = limit || 9
            let offset = page * limit - limit
            let devices;
            if (!brandId && !typeId) {
                devices = await Product.findAndCountAll({ limit, offset })
            }
            return devices
        };
        
       getAllForClient = async (req,res) => {
            let newList=[]
            let devices=await this.getItems(req.query)
            for (let index = 0; index < devices.length; index++) {
              let newItem={
                  name:devices[index].name,
                  price:devices[index].price,
                  videoUrl:devices[idnex].videourl            
              }
              newList.push(newItem)        
            }
            return res.json(newList)
        }
    }

    PS: В дострелочные времена нужно было убедиться, что this это тот самый this в конструкторе класса и передавать в другую переменную класса, например в that, чтобы потом использовать во всех методах.
    Ответ написан
    Комментировать
  • Как распарсить данные из ответа JSON?

    @alexalexes
    Как-то так:
    var container = document.getElementById('какой-то-id-контейнера-куда-вывести');
    container.innerHTML = "<p style='text-align: center'>User info:</p>\
    <table>\
    <tr><td>Name:</td><td>" + response.name + "</td></tr>\
    <tr><td>Username:</td><td>" + response.username + "</td></tr>\
    <tr><td>Address:</td><td>" + response.address.city + ", " + response.address.street  + "</td></tr>\
    <!-- И дальше в таком же духе -->\
    </table>";
    Ответ написан
    Комментировать
  • Виснет страница при проигрывании аудио?

    @alexalexes
    Попробуйте вместо setinterval для отображения текущей позиции использовать подписку на специализированные события элемента audio, например, на timeupdate.
    PS: Ваш плеер на основе тэга audio, надеюсь?
    полоски прогресса и таймера в отдельный поток?

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

    @alexalexes
    Можно воздействовать на конкретный селектор в уже отрендеренных стилях CSS.
    document.styleSheets[i].rules[j].selectorText
    Но проблема в том, что нужно пробежаться по всем стилям (i - счетчик), в каждом стиле просмотреть текст у селектора (j - счетчик).
    Если такой найден, то изменить свойство.
    document.styleSheets[i].rules[j].style['имя_свойства'] = значение_свойства;

    Подробнее:
    https://www.w3.org/wiki/Dynamic_style_-_manipulati...
    Ответ написан
    Комментировать
  • Как лучше добавлять большие куски html на чистом JS?

    @alexalexes
    Причем данные нужно понатыкать в блок так, чтобы было красивенько - а это куча разных span, ul и прочего, что будет расставлять данные в блоке по определенно схеме.

    Эта работа для любого JS шаблонизатора, который вы не хотите использовать.
    А это очень много кода - почти 200 строк шаблонной строки, куда втыкаются полученные данные.

    Для рендеринга DOM важно не количество строк или символов, а количество узлов (тэгов и текстовых блоков). Если у вас узлов в документе меньше тысячи, то любые беспокойства по поводу того, что оно прорисуется не быстро - это экономия на спичках. Если у вас пару десятков или сотен тысяч узлов в блоке, то да, определенные задержки будут.
    В JS-файле все это выглядит не совсем круто, плюс в шаблонной строке очень неудобно писать HTML.

    Да-да, без шаблонизатора, единственный способ сшивать строки в JS:
    Это использовать плюсы:
    var html_str = '<p>'
    + 'какое-то значение'
    + '</p>';

    двойными кавычками с обратным слэшем:
    var html_str = "<p>\
    какое-то значение\
    </p>";

    или обратными кавычками (не для старых браузеров)
    var html_str = `<p>
    какое-то значение
    </p>`;

    Еще нужно заботится об экранировании внутренних кавычек, если такие используются для обрамления всей строки шаблона.
    Да, неудобно, но это плата за отсутствие шаблонизатора.
    Но и этот подход мне не нравится, так как получится очень много операций по встраиванию данных в уже сформированный html. А это, насколько я знаю, очень неэффективно.

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

    @alexalexes
    У ссылки на объект можно менять только скалярные значения, избегая замены всего объекта. Тогда у data будет работать эффект ссылки на this.data.htmlBlocks[elementClass].views. Для переприсваивания объектов нужно брать сам this.data.htmlBlocks[elementClass].views.
    viewsHandler(elementClass){
        let data = this.data.htmlBlocks[elementClass].views;
        let now = new Date().getTime();
        if ( data.lastView && now - data.lastView / 1000 > 15 ) {
          data.views = views.count++; // views который справа за пределами функции?
          data.lastView = now;
          }
        } else {
          data.views = 2;
          data.lastView = 1;
          }
          
        }
      }
    Ответ написан
    1 комментарий
  • Как принимать сообщения от посетителей об ошибках на сайте?

    @alexalexes
    Выделите ошибку и нажмите одновременно клавиши «Ctrl» и «Enter»

    Такой функционал был популярен в начале 2000-х, когда основное место в содержимом сайта занимал текст, а верстка была вполне примитивна.
    В сегодняшнее время проблемы на сайте могут быть не только в текстовом содержимом, но и в интерактивном функционале, а такое можно зафиксировать только скриншотом.
    Поэтому, не критично, если у вас на сайте не будет такого функционала с выделением ошибки. Главное, дать возможность отправить сообщение администрации сайта любым доступным способом. Туда хоть копируй текст, хоть делай скриншот.
    Добавлено:
    Для мобильной версии сайта единственный выход - отображать ссылку или кнопку "Сообщить об опечатке" после основного текстового содержания, нажатие на которую вызывает тот же обработчик, что и Ctrl + Enter.
    Ответ написан
  • Отправка изображения canvas на сервер PHP?

    @alexalexes
    btn_send.addEventListener('click',async() => {
        let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
        let formData = new FormData(); // Создаем объект формы для наполнения данными, словно мы работаем с тегом form в html.
        formData.append('canvas_field', blob, 'canvas.png'); // это эквивалент тому, что в нашей html форме создаем поле input type="file" name="canvas_field" value="canvas.png" и прикрепляем туда содержимое blob (метод append сам расшаривает blob, дополнительных преобразований не требуется). Естественно, на DOM-дереве это никак не отразится, это модель формы в памяти JS.
        let response = await fetch('web_tp_word.php', {
        method: 'POST',
        body: formData // для fetch не нужно дополнительных параметров, чтобы объяснить как работать с formData. Идеально, чтобы завернуть файл в форму и отправить на сервер.
        });
    });

    На стороне сервера:
    var_dump($_FILES['canvas_field']); // Сервер при вызове скрипта сложит данные файла во временный файл, а как их получить - в $_FILES. Далее можно обрабатывать всеми теми способами, предназначенные для работы с $_FILES. И после уже неважно, как их сгенерировали на клиенте.
    Ответ написан
    1 комментарий
  • Помощь с пониманием устройства debounce?

    @alexalexes
    ...args
    arguments
    Это специальные объекты JavaScript. Их заполняет сама среда интерпретарора JS, когда становится активным контекст вызываемой функции. Очень помогает обрабатывать аргументы функции, когда их количество неизвестно заранее, или нужно специально сделать такую функцию, которая обрабатывает произвольное число аргументов.
    какая из реализаций лучше?
    Если стоит задача написать полифил для поддержки старых версий браузера, то следует использовать объекты JS, которые поддерживаются как можно в ранней версии стандарта языка (смотрите таблицу совместимости браузеров с тем или иным стандартным объектом).
    Если такой задачи нет, то берем стильные, модные, молодежные языковые конструкции.
    Ответ написан
    Комментировать
  • Почему событие onchage не срабатывает для select?

    @alexalexes
    Есть события: click, change, input и т.д.
    Привязка обработчика соответствующего события с использованием атрибута тэга осуществляется с приставкой on:
    <select id="selectTheme" onchange="alert('Theme changed')">
    </select>

    Но в тоже время, привязка обработчика события с использованием addEventListener не требует указания on, берется само название события и с названием атрибута не нужно путать:
    sel.addEventListener('change', (event) => {
        	alert('Theme changed');
        })
    Ответ написан
    3 комментария
  • Как собрать в один массив несколько переменных из input с одинаковыми ID?

    @alexalexes
    Если наступить на горло веб стандарту, игнорируя условие уникальности, то к id нужно относиться как обычному атрибуту тега. Следовательно, для захвата всех элементов с одинаковым id в коллекцию нужно использовать селектор вида:
    input[id="id_imgs"]
    Ответ написан
    1 комментарий