Ответы пользователя по тегу JavaScript
  • Явный и не явный возврат функции, что это значит и в чем разница?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Явный:
    через ключевое слово return.
    Например:
    function getTrue() {
      return true // явный возврат true
    }
    getTrue() // true
    
    const getFalse = () => {
      return false // явный возврат false из стрелочной функции
    }
    getFalse()  // false

    То есть Вы с помощью зарезервированного слова говорите "в слух" - вот тут я возвращаю такое то значение.

    Неявный:
    - Для обычных функций это когда функция не содержит слова return и возвращает undefined по умолчанию.
    - Для стрелочных функций, когда функция записана в одну строку и не содержит слова return, но возвращает значение операции, описанной после =>. Если стрелочная функция с описанным в фигурных скобках телом функции, то так же как и для обычной функции. Если нет return, то undefined.

    Например:
    function getUndefined() {
      // какой то код, но нет return.
      console.log('Я тут что-то делаю, не обращайте внимания.')
    }
    getUndefined() // undefined
    
    const getArrowValue = () => 'неявный'
    getArrowValue() // "неявный"

    То есть Вы нигде не говорите напрямую что возвращаете определённое значение с помощью зарезервированного ключевого слова.

    И для чего это
    Если честно даже не знаю что на это ответить. Чтоб было. Ну вот есть такие вот варианты и всё. Ну неявный в стрелочной чтоб было короче разве что.
    Ну ещё немного подумав - неявный возврат из функции может быть только один - в самом конце функции. Явных возвратов в функции может быть несколько. Например если по условию нужно вернуть разные значения. При этом наличие явного возврата в функции не гарантирует что он сработает, опять же, если он находится под условием.
    Например:
    function conditionalReturn(value) {
      if (value === 1) {
        return 'one'
      }
      if (value === 2) {
        return 'two'
      }
    }
    
    conditionalReturn(1) // явно вернёт one
    conditionalReturn(2) // явно вернёт two
    conditionalReturn(3) // не явно вернёт undefined


    UPD:
    Так же асинхронная функция, объявленная через ключевое слово async, в неявном виде всегда возвращает Promise, даже если используется ключевое слово return - то значение после return будет обёрнуто в промис.
    Ответ написан
    Комментировать
  • Почему не добавляется класс?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    document.querySelector('[data-tab="tab-1"]').classList.add('accordion__title-active');
    [data-tab="tab-1"] - нет такого элемента. Скрипт падает с ошибкой.
    document.querySelector('#tab-1') аналогично, #tab-1 - нет такого элемента.

    Исправление этих ошибок приводит код в рабочее состояние.

    Научитесь читать сообщения в консоле и отладке своего кода.
    https://learn.javascript.ru/debugging-chrome
    Ответ написан
  • Чем отличается событие клика от button.click();?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Чем отличается событие клика от button.click()

    Событие вызывается когда пользователь нажмёт на кнопку.
    button.click() - программный тригер клика на кнопке без участия пользователя. То есть клик из под скрипта.

    Объект event, который пробросится в обработчик клика будет не одинаковый.
    Например, будет отличаться свойство isTrusted - у программного клика будет false.

    Ну и не на всё можно сделать клик програмно.

    Как вообще сформулировать гуглу запрос на эту тему, что бы статью какую-то почитать

    - События и обработка событий в javascript.
    - Эвент луп, микро и макро таски

    Ну и обо всём в js стоит начинать поиск отсюда https://learn.javascript.ru/
    Например, события - https://learn.javascript.ru/introduction-browser-events

    Вот тут вроде описано почему разные результат между пользовательским кликом и программным. Рекомендую всю статью к изучению
    https://jakearchibald.com/2015/tasks-microtasks-qu...
    Перевод на хабре: https://habr.com/ru/post/264993/
    Ответ написан
    Комментировать
  • Из-за чего может ездить форма в мобильной версии?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Из-за снежинок. Они у Вас расстягивают контейнер. Плавает не только форма. Нижнее мобильное меню тоже.

    Первый же div внутри body стоит overflow: visible. Поменяйте на hidden.
    Ответ написан
  • Как регулярным выражением получить дату из строки?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    "2023-02-01 13:00:00".split(' ')[0].split('-')[2] // 01
    // или
    "2023-02-01 13:00:00".match(/\d{4}-\d{2}-(\d{2})\s\d{2}:\d{2}:\d{2}/)[1] // 01
    // или
    "2023-02-01 13:00:00".replace(/\d{4}-\d{2}-(\d{2})\s\d{2}:\d{2}:\d{2}/, '$1') // 01
    // или
    new Date("2023-02-01 13:00:00").getDate() // 1
    // или
    new Date("2023-02-01 13:00:00").getDate().toString().padStart(2,0) // 01
    Ответ написан
    1 комментарий
  • Как открыть другой файл html через условие js?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    window.location = 'https://qna.habr.com/q/1245342'
    // ну а если в рамках текущего домена то без протокола.
    // Например, находясь на странице https://vk.com/feed чтобы перейти на https://vk.com/im достаточно будет
    window.location = 'im'
    Ответ написан
    Комментировать
  • Как выбрать нужный элемент?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    const index = 2
    const items = document.querySelector(`.parent .child:nth-child(${index})`)
    // или 
    const items = document.querySelectorAll('.parent .child')
    const thirdItem = items[index]

    P.s. только эти две записи вернут разный элемент, потому что в css нумерация не с нуля в nth-child.
    Ответ написан
    Комментировать
  • Почему у сайта такие странные классы?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    У вас querySelector выдаёт null. Выше, в тексте ошибки.
    То, что на других сайтах работает, не значит что везде будет работать. Значит на других сайтах блоки которые вы меняете не асинхронно подгружаемые или загружаются раньше чем расширение .

    Тут можно посмотреть в сторону mutation observer, либо в head добавить кастомную секцию style где будет css меняющий стили этого блока с important. То есть найти элемент head, создать элемент style, задать текстовое содержимое для style - css правило, добавить style в head.

    Код от автора вопроса, решивший проблему по вышеописанному лагоритму:
    let head = document.getElementsByTagName('head')[0];
    let styleR = document.createElement('style');
    head.appendChild(styleR);
    styleR.innerHTML =
      '.amber-button_theme_accent { background-color: #FA8072 !important; }';
    head.appendChild(styleR);
    Ответ написан
    Комментировать
  • Всплывающеий блок при наведении мышки, hover, как заменить на клик?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Например, с помощью чекбокса.
    <label for="trigger">Пробег</label>
    <strong>Выбрать</strong>
    <input type="checkbox" id="trigger">


    #trigger:checked ~ .prcr {
    /* .pro:hover .prcr { */
      display: block;
      opacity: 1;
      visibility: visible;
      -webkit-transition-delay: 0s;
      transition-delay: 0s;
    }


    Осталось его скрыть и увеличить зону кликабельности лэйбла как Вам надо, а не только на слово "Выбрать"
    Ответ написан
    8 комментариев
  • Почему после добавления нового блока слетают события со всех остальных?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    После этого и срабатывает этот блок success. где отрисовывается новый блок.

    document.getElementById('client-personal-note-container').innerHTML += appendNotemakrup;

    Нет, это НЕ добавление нового элемента.
    Это чтение разметки КАК СТРОКИ, добавление к этой СТРОКЕ новой СТРОКИ и потом преобразование под капотом в DOM элементы. Понимаете?

    То есть все элементы что у Вас были - умирают и заменяются НОВЫМИ. Без добавленных на них ранее обработчиков.

    Как исправить?
    Основных пути 2:
    1) Научиться именно добавлять элементы https://learn.javascript.ru/modifying-document
    2) Освоить делигирование событий https://learn.javascript.ru/event-delegation
    Ответ написан
    1 комментарий
  • Почему каждый раз выдаёт undefined?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Вас совершенно не смущает что alert Вы делаете на первой строчке в функции example, а инициализацию переменной на 13ой?

    Тело функции выполняется каждый раз заново.
    Чтобы сработало так как Вы хотите, нужно определить переменную ВНЕ функции и убрать var для buffer внутри функции. (но для первого раза всё равно будет undefined, хотя если вне функции инициализировать переменную так же как и внутри функции, через querySelector().innerHTML, то будет ок).

    А вот чтоб прям совсем работало, даже с первого раза, то сначала нужно объявлять переменную, а потом использовать, а не наоборот.
    Ответ написан
    1 комментарий
  • Почему return не возвращает числовое значение?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    На примере этого участка:
    select.addEventListener('change', function () {  
      formValidation(form);
      console.log(errors);
      ine.innerHTML = errors;
    });

    Так Вы никуда значение и не присваиваете, которое возвращает функция formValidation.
    console.log(errors) - errors не существует в данной области видимости. Функции возвращают значение, которое хранится в переменной, а не переменную с её названием в область видимости, где функция была вызвана.

    Таким образом:
    select.addEventListener('change', function () {  
      const errors = formValidation(form);
      console.log(errors);
      ine.innerHTML = errors;
    });
    Ответ написан
    1 комментарий
  • Почему игнорируется условие if?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    1. Если что-то не работает как задумано, первое что нужно сделать это открыть инструменты разработчика на вкладке console и посмотреть нет ли там никаких ошибок. Если есть то загуглить их и посмотреть где они возникают. Попытаться осознать и исправить. А ещё лучше научиться отладке собственного кода https://learn.javascript.ru/debugging-chrome
    2. Перед тем как пользоваться тем или иным способом объявления переменных (var\let\const) стоит почитать про него и ознакомиться с нюансами.
    https://medium.com/nuances-of-programming/%D0%B2-%...

    А именно:
    if (parseInt(number.innerHTML) == 0){
      let step = 3;
      } else {
      let step = parseInt(number.innerHTML) - 1;
      }

    Переменной step не существует вне фигурных скобок, соответственно, ниже, где Вы пытаетесь засунуть step как innerHTML - возникает ошибка, что step не определена.
    Ответ написан
    2 комментария
  • Сделать область регистрации касания "шире" без изменения параметров самого элемента?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Псевдоселекторы псевдоэлементы типа :before

    Но тут ещё стоит учесть ситуацию, когда 2 элемента окажутся рядом друг с другом. Что тогда? Ну, очевидно, один из них будет пеекрывать другой по z-index. Но вероятность что это будет не тот что нужно - высока. В итоге пользоватею нужно будет сначала убрать перекрывающий элемент, поправить целевой, вернуть обратно перекрывающий, а если их несколько?

    Поэтому варианта я вижу 3 и их лучше всего совместить:
    1) Расширить зону через псевдо
    2) Делать выбор элемента по тапу. То есть тапнул на элемент, он выделился - и потом с ним взаимодействуетшь. Если нессколько элементов лежат друг под другом, то выбирать последовательно на каждый тап следующий элемент. Первый тап выбирает самый верхний, второй тап выбирает лежаший под и так далее.
    Найти все элементы в координатах тапа поможет метод https://developer.mozilla.org/en-US/docs/Web/API/D...
    3) Сделать условный select в котором можно будет выбрать нужный элемент. В идеале - если каждый элемент будет как-то уникально промаркрован.

    Ну и ещё можно дать возможность зумить чтобы элементы становились больше, что облегчит взаимодействие с ними
    Ответ написан
    Комментировать
  • Как получить новый объект с посчитанными суммами?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    const out = items.reduce((acc, {id, price}) => {
      const key = obj[id]
      if (key) { // проверяем что элемент с таким id нас вообще интересует
        if (acc[key]) { // если он встречался ранее, то добавляем к текущему значению
          acc[key] += price
        } else { // иначе запоминаем с текущей ценой
          acc[key] = price
        }
        acc.total += price // и всегда добавляем к total
      }
      return acc
    }, { total: 0 })
    Ответ написан
    Комментировать
  • Почему touch slider (не плагин) не работает когда я открываю консоль?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    а с чего Вы решили, что у Вас touch слайдер? Где хоть один обработчик события touch*...?
    Вижу только обработчики mouse* события.

    В эмуляции девайса как раз включается эмуляция тача.

    UPD: fix на скорую руку. Стоит конечно же вынести функции отдельно, чтобы не дублировать.
    fix

    let slider = document.querySelector('.container-3_1');
    let innerSlider = document.querySelector('.container-3-1_blocks');
    
    
    let pressed = false;
    let startx;
    let x;
    
    slider.addEventListener('mousedown', (e)=> {
        pressed = true;
        startx = e.offsetX- innerSlider.offsetLeft;
        slider.style.cursor = 'grabbing'
    })
    
    slider.addEventListener('touchstart', (e)=> {
        pressed = true;
        const evt = e.touches[0]
        startx = evt.clientX- innerSlider.offsetLeft;
        slider.style.cursor = 'grabbing'
    })
    
    slider.addEventListener('mouseenter', ()=> {
        slider.style.cursor = 'grab'
    })
    
    slider.addEventListener('mouseup', ()=> {
        pressed = false;
        slider.style.cursor = 'grab'
    })
    
    slider.addEventListener('touchend', ()=> {
        pressed = false;
        slider.style.cursor = 'grab'
    })
    
    
    slider.addEventListener('mousemove', (e)=> {
        if(!pressed) return;
        e.preventDefault();
    
        x = e.offsetX;
    
        innerSlider.style.left = `${x - startx}px`
        
    
        checkboundary()
    })
    
    slider.addEventListener('touchmove', (e)=> {
        if(!pressed) return;
        e.preventDefault();
    
        const evt = e.touches[0]
        x = evt.clientX;
    
        innerSlider.style.left = `${x - startx}px`
        
    
        checkboundary()
    })
    
    
    function checkboundary(){
        let outer = slider.getBoundingClientRect();
        let inner = innerSlider.getBoundingClientRect();
    
        if(parseInt(innerSlider.style.left) > 0) {
            innerSlider.style.left = '0px'
        } else if (inner.right < outer.right){
            innerSlider.style.left = `-${inner.width - outer.width}px`
        }
    }

    Ответ написан
    Комментировать
  • Как Кинопоиск делает черный квадрат в захвате экрана?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Судя по всему - они это делают на основе DRM.
    Первый ответ на СО содержит ссылку на статью про это где есть демка, где работает точно так же.
    Ответ написан
    7 комментариев
  • Как исправить ошибку $(...).X is not a function?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Скорее всего код, где выбрасывается ошибка - либо не корректный, либо преждевременный.
    Попробуйте закомментировать его и проверить.
    Ответ написан
    1 комментарий
  • Почему функция возвращает массив с теме же данными?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Потому что Вы не прочитали документацию по методу.

    https://developer.mozilla.org/ru/docs/Web/JavaScri...
    Возвращаемое значение
    Массив, содержащий удалённые элементы.


    Соответственно, return [].splice() возвращает массив из элементов, которые были удалены.
    А ещё метод - деструктивный. То есть меняет исходные данные. arrayTaskOne, объявленный вне функции, изменился, а это не хорошо.
    Почему не хорошо? Гуглите по теме: чистые функции, сайд эффект
    Ответ написан
    Комментировать
  • Почему код при клике выполняется 2 раза?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Скорее всего потому, что у Вас инпут лежит внутри label.
    Если в таком случае вешать обработчик на label то будет двойное срабатывание.
    Можно повесить на сам инпут, либо связать лэйбл с инпутом через for
    Ответ написан
    4 комментария