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

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ну во-первых, querySelectorAll возвращает коллекцию NodeList а не массив, это важно понимать.
    Во-вторых, у NodeList нет сеттера onclick в отличии от элементов, а следовательно Ваше присваивание туда функции просто не сработает.
    В-третьих, не стоит пользоваться сеттерами вида oneventname, так как это чревато проблемами, используйте метод addEventListener
    В-четвертых, querySelectorAll можно использовать не только на document, но и на элементах
    В-пятых, в обработчик события приходит объект события в качестве аргумента, в котором есть свойство target - элемент на котором событие произошло

    По-итогу:
    function listener(event) {
      const target = event.target.closest('.app__item');
      target.querySelectorAll('.equalizer').forEach(
        elem => elem.style.display = 'block'
      );
      // так как дальнейшие клики будут гонять бесполезный цикл, то лучше отписаться
      target.removeEventListener('click', listener);
    }
    document.querySelectorAll('.app__item').forEach(
      item => item.addEventListener('click', listener)
    );
    Ответ написан
    Комментировать
  • Можно ли поместить(записать) переменные в массив?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В js многие операторы не являются выражением, и как следствие их можно использовать только как statement.
    Среди них var, let, const, return, throw (есть пропозал, так что в будущем может изменится), if, for, while и некоторые другие.
    следовательно написать x = delete y.z можно, так как оператор delete - является выражением и возвращает true или false
    а написать x = var y нельзя, так как var ничего не возвращает, даже undefined не вернет.

    можно так:
    var arrey = [];
    var a = 1;
    var b = 2;
    arrey[0] = a;
    arrey[1] = b;

    но правильнее так:
    var arrey = [];
    var a = 1;
    var b = 2;
    arrey.push(a, b);
    или так:
    var a = 1;
    var b = 2;
    var arrey = [a, b];
    Ответ написан
    Комментировать
  • Как передать элемент в callback функцию?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Передавать его еще одним аргументом в loadScript
    let loadScript = (url, callbackScript, elem) => {
        let script = document.createElement('script');
        script.src = url;
        document.getElementsByTagName('body')[0].append(script);
        script.onload = function() {
          callbackScript(elem); // Как в эту функцию передать elem? elem находится снизу при обходе массива
        };
      };
    App.prototype.initModule = function(array) {
        array.forEach(elem => {
          loadStyles.call(DATA, DATA[elem].styleURL); // Вот здесь передаю callback
          loadScript.call(DATA, DATA[elem].scriptURL, callback, elem);
        });
      };


    P.S. метод call не имеет смысла для стрелочных функций, ибо у них нет своего this
    Ответ написан
    2 комментария
  • Можете объяснить для нужна опция body в Fetch?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/API/Requ...
    В запросе - это тело запроса, может быть строкой, Blob, ArrayBuffer или FormData

    https://developer.mozilla.org/en-US/docs/Web/API/R...
    В ответе - Readable Stream с телом ответа
    Так же в ответе есть методы для чтения и парсинга тела возвращающие промис
    https://developer.mozilla.org/en-US/docs/Web/API/R...

    Сам fetch принимает или объект запроса или url и параметры запроса, то есть body там как у запроса
    Ответ написан
    Комментировать
  • Как написать функцию для валидации CSS кода?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    1. Распарсить текст в токены
    2. Построить из токенов AST
    Если оба шага успешны - true, если хоть где-то не вышло - false
    Семантика есть в официальной спеке
    Ответ написан
    1 комментарий
  • Как упростить этот javascript код?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const content = document.body.querySelector('.editer');
    const htmlTags = content.getElementsByTagName("*");
    const navs = []; // здесь let не нужен
    
    for(let i = 0; i < htmlTags.length; i++) {
      const htmlTag = htmlTags[i];
      const lastNav = navs[navs.length - 1]; // resH2 всегда будет таким (см. комменты ниже)
      const lastChildOfLastNav = lastNav && lastNav.children[lastNav.children.length - 1]; // resH3 всегда будет таким
      switch(htmlTag.localName) {
      case 'h2':
        setID(htmlTag, i);
        addItem(navs, htmlTag);
        break;
      case 'h3':
        setID(htmlTag, i);
        // тот find что у Вас всегда найдет последний элемент если он есть, не зачем гонять лишний цикл
        if(lastNav) {
          addItem(lastNav.children, htmlTag);
        }
        break;
      case 'h4':
        setID(htmlTag, i);
        // опять же был лишний цикл ради последнего элемента, да еще и в него вложен такой же
        if(lastChildOfLastNav) {
          addItem(lastChildOfLastNav.children, htmlTag);
        } else if(lastNav) {
          addItem(lastNav.children, htmlTag);
        }
        break;
      }
    }
    
    function addItem(obj, {innerText: name, id}) {
      obj.push({
        name,
        id,
        children: []
      });
    }
    
    function setID(htmlTag, i) {
       htmlTag.setAttribute('id', `nav-${i}`);
    }
    Ответ написан
    Комментировать
  • Серия книг "You dont know js" - стоит ли начинать читать?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Есть ли смысл начинать читать её сейчас, или на сегодняшний день она уже слишком устарела?
    Фундаментальные знания не устаревают никогда, а в данной книге именно фундамент.
    насколько я понимаю, написана она опираясь на старый стандарт
    Даже оператор with, который deprecated начиная с es5 можно использовать в самом современном движке js. Каждая новая версия ES лишь дополняет предыдущую, но не отменяет ее, хотя некоторые вещи и становятся нежелательными (вроде использования var после появления let и const), новые вещи основываются на старых (иначе бы babel не работал). Ну а то немногое, что совсем deprecated (вроде оператора with или глобального объекта в качестве this по умолчанию) - как правило плохие практики и в таких книгах почти не освещаются
    Ответ написан
    Комментировать
  • Почему не работает autoplay в Plyr на мобильках?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Play со звуком возможен только синхронно после действия пользователя (клик мыши, нажатие кнопок клавиатуры).
    Проверить, что событие инициировано пользователем можно с помощью event.isTrusted
    Autoplay можно запустить без звука, притом на медиа элементе (теги video, audio) должно быть именно mediaEl.muted = true, а mediaEl.volume = 0 не поможет
    Десктопные браузеры тоже могут блокировать воспроизведение со звуком, но применяют другие политики, например используется статистика (общая и персонально пользователя) для выявления адекватных сайтов с автовоспроизведением (например ютуб и яндекс видео скорее всего запустятся у всех без особых проблем, т.к. пользователи очень часто запускают на них видео)
    Ответ написан
    Комментировать
  • Как правильно передать параметры в функцию-обработчик чтобы потом его можно было удалить?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    На моей практике лучшим методом работой с различными EventEmitter/PubSub механизмами - это подписыватель возвращающий отписыватель. То есть некая функция, которая на основе своих аргументов организует подписку и возвращает функцию без аргументов, которая при вызове отменит подписку, отпишет от события и т.д.
    Пример из личной библиотеки:
    import {curry} from 'ramda';
    export const subscribe = curry((target: EventTarget, eventName: string, handler: EventListenerOrEventListenerObject): (() => void) => {
        target.addEventListener(eventName, handler);
        return () => target.removeEventListener(eventName, handler);
    });

    Если убрать ramda и typescript, то останется такое:
    export const subscribe = (target, eventName, handler) => {
        target.addEventListener(eventName, handler);
        return () => target.removeEventListener(eventName, handler);
    };

    Суть: subscribe при вызове подпишет DOM объект target на событие eventName с функцией handler и вернет функцию без аргументов, которая при вызове отпишет DOM объект target от события eventName для функции handler

    В Вашем случае будет так:
    const curry = (i) => (e) => changeCountry(e, i);
    const unsubscribe = subscribe(button, 'click', curry(i));
    // когда подписка больше не нужна, просто вызываем unsubscribe()
    Ответ написан
    Комментировать
  • Как избавится от ошибок в npm и начать жить счастливо?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Скачивание электрона отвалилось по таймауту, переустановите
    Ответ написан
    Комментировать
  • Почему Uncaught (in promise)?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Потому что y обрабатывается только в случае успешного x, а у Вас оба промиса реджектятся
    И так как второй остается не обработанным, он падает, когда очередь доходит до него
    Ответ написан
  • Как сделать кроссдоменный запрос локально?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Access-Control-Allow-* заголовки должен отправлять сервер, а не клиент
    Ответ написан
  • Не работает метод Array.from?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    HTML коллекции динамические, когда Вы их выводите в консоль, они вполне себе пустые, но когда смотрите, консоль синхронизируется и показывает Вам заполненную коллекцию.
    Когда Вы преобразуете коллекцию в массив, в массиве оказывается текущие элементы, которых еще нет. И так как массив ничего не знает о Вашем DOM, то ничего и не появится в дальнейшем.
    Нужно дожидаться, пока элементы появятся на странице, и только потом работать с ними, например с помощью события DOMContentLoaded на document
    Ответ написан
    5 комментариев
  • Javascript framework, который использует "$"?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Классическая реализация метода noConflict() выглядит примерно так:
    const original = globalThis.libraryVariable; // сохраняем предыдущее значение заменяемой переменной
    globalThis.libraryVariable = libraryExport; // перезаписываем нашей либой
    libraryExport.noConflict = () => {
      globalThis.libraryVariable = original; // восстанавливаем сохраненное значение
      return libraryExport; // возвращаем нашу либу
    };
    где:
    globalThis - стандартное (начиная с ES2020) имя для глобального объекта (window, self - в браузере, global - в ноде - псевдонимы)
    libraryVariable - глобальная переменная содержащая библиотеку, в случае с jQuery таких переменных 2 - $ и jQuery
    libraryExport - внутренняя переменная, которая так же хранит ссылку на библиотеку (это нужно, чтоб либа не сломалась, даже если Вы руками измените глобальную переменную)

    P.S. в современном мире большинство библиотек по возможности используют модульную систему и не засоряют глобальный объект
    Ответ написан
    Комментировать
  • Асинхронный try, catch в JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Почему catch не ловит ошибку, если он должен ждать, пока не выполнится try
    Потому что try закончит выполнение до throw
    Как поймать асинхронную ошибку??
    Гуглите: js Promise
    Гуглите: js async/await
    В качестве факультатива можно погуглить:
    Почему try/catch зло
    Монада Result/Either
    Ответ написан
    Комментировать
  • Как сделать плагин для jQuery используя Webpack?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • При каких обстоятельствах возникает такой баг?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    debugger Ваше все
    Ответ написан
    Комментировать
  • Как удалить cookie через 5 минут после клика на кнопку?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    $('#click').on('click', 'submit', function() {
        // 5 min == 300sec
        document.cookie = 'userSubmitClick=1; path=/; max-age=300';
    });

    и все, браузер удалит куку сам, даже если вкладка будет закрыта
    и не нужно изобретать велосипеды
    Ответ написан
    5 комментариев
  • Почему лагает браузер при запуске javascript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Вместо
    while (true) {
    msg1();
    msg2();
    sleep(1000);
    }
    делаем это:
    !(function run() {
    msg1();
    msg2();
    sleep(1000).then(run);
    })();
    но теорию почитать все же стоит
    Ответ написан
  • Как сделать такой же курсор как в примере?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Внутренний ромбик - просто кастомный курсор
    гуглим: css custom cursor

    Внешний - блок с pointer-events: none и position: fixed
    скриптами бегает за настоящим курсом и меняет css классы при наведении на определенные элементы или уходе курсора со страницы.

    В конкретном сайте исследуйте элемент с id magic-cursor и его потомков
    Ответ написан
    Комментировать