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

    0xD34F
    @0xD34F Куратор тега JavaScript
    Индекс неправильный. Нужное вам значение передаётся первым параметром в each:

    $('.container').find('h2, h3').each(function(i) {

    Его и используйте:

    text = $('.select-list li a').eq(i).text();
    Ответ написан
  • Как выводить нужный символ в зависимости от числа?

    0xD34F
    @0xD34F Куратор тега JavaScript
    не надо код, подскажите алгоритм

    Думаю, это уже не актуально - раз вы опубликовали собственный вариант. Так что просто код:

    function shorten(val) {
      if (val <= 10000) {
        return val.toString();
      }
    
      const thousands = val / 1000;
      const rounded = Math.round(thousands);
      const deviation = Math.sign(thousands - rounded);
    
      return `${[ '≈', '', '>' ][deviation + 1]}${rounded} т.`;
    }
    Ответ написан
    1 комментарий
  • Как посчитать общую сумму если убрать select?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Ну и откуда тогда должна браться цена, если селект с ценой отсутствует? Можете подставлять случайное значение - как, подойдёт такой ответ? Нет? Тогда дополняйте вопрос.

    UPD.

    Цена завернута в див price prc-new

    ОК, тогда замените

    $('[name="variant"] option:checked').data('price')

    на

    $('.price.prc-new span').text()
    Ответ написан
    Комментировать
  • Как запретить ввод чисел больше 999 в input[type="number"]?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('input').on('input', function() {
      $(this).val((i, v) => Math.max(this.min, Math.min(this.max, v)));
    });

    или

    document.querySelector('input').addEventListener('input', ({ target: t }) => {
      t.value = Math.max(t.min, Math.min(t.max, t.value));
    });
    Ответ написан
    1 комментарий
  • Форматирование чисел на js. Как сделать пробелы в цене?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('.price').text((i, text) => {
      const [ price, currency ] = text.split(' ');
      return `${(+price).toLocaleString()} ${currency}`;
    });
    
    // или
    
    document.querySelectorAll('.price').forEach(n => {
      n.textContent = n.textContent.replace(/\d(?=(\d{3})+\D)/g, '$& ');
    });

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

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вместо того, чтобы вручную переключать классы каждого блока, сделаем функцию, которая будет принимать блок в качестве параметра и выполнять все необходимые действия:

    function toggleClasses(block) {
      const info = block.querySelector('.infoWrapper');
      block.classList.toggle('marginBottom10');
      block.classList.toggle('marginBottom120');
      info.classList.toggle('displayNone');
      info.classList.toggle('displayBlock');
    }

    Подключение отдельных обработчиков клика к каждой кнопке заменим одним делегированным обработчиком, а вместо ручного перебора всех блоков просто будем искать открытый:

    document.addEventListener('click', function(e) {
      const block = e.target.closest('.blockSvg');
      if (block) {
        const prevBlock = document.querySelector('.blockSvg.marginBottom120');
        if (prevBlock && prevBlock !== block) {
          toggleClasses(prevBlock);
        }
    
        toggleClasses(block);
      }
    });

    В результате, объём кода сократился на два порядка.

    Ну и конечно, надо перевёрстывать, потому что вот это вот "подправляем положение блоков" - позорище какое-то.
    Ответ написан
    1 комментарий
  • Как изменить содержимое всех найденных элементов на странице с помощью jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    В каких элементах и на сколько надо ограничить длину текста:

    const className = 'dop_atr';
    const maxlen = 250;

    Чтобы все элементы обрабатывались индивидуально, вместо строки можно передавать в метод text функцию - вызывается для каждого элемента набора, принимает текущее текстовое содержимое элемента и возвращает новое:

    $(`.${className}`).text((i, text) => {
      return text[maxlen] ? `${text.substring(0, maxlen)}...` : text;
    });

    Или, можно отказаться от jquery:

    for (const n of document.getElementsByClassName(className)) {
      n.innerText = n.innerText.slice(0, maxlen) + (n.innerText.charAt(maxlen) && '...');
    }
    
    // или
    
    document.querySelectorAll(`.${className}`).forEach(function(n) {
      n.textContent = n.textContent.replace(this, '$1...');
    }, RegExp(`(.{${maxlen}}).+`));
    Ответ написан
    Комментировать
  • Как отмечать определенные checkbox при клике по ссылке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.addEventListener('click', function(e) {
      const el = document.getElementById(e.target.dataset.id);
      if (el) {
        el.checked = !el.checked;
      }
    });

    или

    const buttons = document.querySelectorAll('[data-id]');
    const onClick = e => checkboxes[e.target.dataset.id].checked ^= 1;
    const checkboxes = Array
      .from(buttons, n => n.dataset.id)
      .reduce((acc, n) => (acc[n] = document.querySelector(`#${n}`), acc), {});
    
    buttons.forEach(n => n.addEventListener('click', onClick));
    Ответ написан
    Комментировать
  • Можно ли строку перевести в объект?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('.tab__list').on('click', '.tab__item', function() {
      const
        $this = $(this),
        { label, ...attrs } = text[$this.data('tab')];
    
      $this.siblings().removeClass('tab__item--active');
      $this.addClass('tab__item--active');
      $('#formField').attr(attrs);
      $('#formLabel').text(label);
    });
    Ответ написан
    6 комментариев
  • Как на jQuery поменять стиль у label с активным input radio?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вместо

    .red{border:3px solid red;;}
    .green{border:3px solid red;;}

    пусть будет

    .items-list-item-colors label {
      border: 3px solid red;
    }
    
    .items-list-item-colors label.active {
      border-color: green;
    }

    Соответственно, из разметки class="red" вырезаете.

    Где, кому и какой класс будем переключать:

    const containerSelector = '.items-list-item-colors';
    const itemSelector = 'label';
    const activeClass = 'active';

    Такие есть варианты:

    $(containerSelector).change(function() {
      $(itemSelector, this)
        .removeClass(activeClass)
        .has(':checked')
        .addClass(activeClass);
    });
    
    // или
    
    document.querySelectorAll(containerSelector).forEach(n => {
      n.addEventListener('change', onChange);
    });
    
    function onChange({ target: t }) {
      this.querySelectorAll(itemSelector).forEach(n => {
        n.classList.toggle(activeClass, n.contains(t));
      });
    }
    
    // или
    
    document.addEventListener('change', e => {
      const item = e.target.closest(itemSelector);
      if (item) {
        item.closest(containerSelector).querySelectorAll(itemSelector).forEach(n => {
          n.classList.toggle('active', n === item);
        });
      }
    });
    Ответ написан
    Комментировать
  • Как удалить копии добавленного блока?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Добавляете блок в случае, если его нет:

    const $inner = $('.inner');
    if (!$inner.find('.butt_back').length) {
      $inner.append(...);
    }


    Или, если вам действительно надо удалять предыдущие:

    $('.inner')
      .find('.butt_back').remove()
      .end()
      .append(...);
    Ответ написан
    Комментировать
  • Почему не работает клонирование canvas?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Что не так ?

    Да всё не так.

    Что за clone? - у DOM-узлов такого метода нет. Есть cloneNode. Или используйте jquery (судя по тому, что контекст вы пытаетесь получить у clone[0], так и предполагалось), там clone есть: $(canvas).clone().

    Копировать содержимое оригинала вы пытаетесь до того, как оно вообще будет загружено. Выполняйте копирование в onload.

    Копируете непонятно откуда:

    canvas = document.getElementById('myCanvas');
    <...>
    drawImage(canvas[0],

    Опять же - либо canvas = $('#myCanvas'), либо drawImage(canvas,.

    UPD. Должно было быть так?
    Ответ написан
    3 комментария
  • Как запустить функцию только один раз?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Удаляйте обработчик после того, как он выполнил нужное действие:

    $(window).scroll(function onScroll() {
      const $this = $(this);
      if ($this.scrollTop() > scrollToElem) {
        $('#popup-item').addClass('popup-open');
        $this.off('scroll', onScroll);
      }
    });
    Ответ написан
    Комментировать
  • Как остановить setInterval из другой функции?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.addEventListener('mouseover', ({ target: t }) => {
      if (t.classList.contains('pic') && !t.dataset.interval) {
        t.dataset.interval = bgRotate(t);
      }
    });
    
    document.addEventListener('mouseout', ({ target: t }) => {
      const { interval } = t.dataset;
      if (interval) {
        clearInterval(interval);
        delete t.dataset.interval;
      }
    });

    или

    document.querySelectorAll('.pic').forEach(n => {
      n.addEventListener('mouseenter', onHover);
      n.addEventListener('mouseleave', onHover);
    });
    
    function onHover({ type, target: t }) {
      const d = t.dataset;
      if (type === 'mouseenter' && !d.interval) {
        d.interval = bgRotate(t);
      } else if (type === 'mouseleave') {
        clearInterval(d.interval);
        delete d.interval;
      }
    }
    Ответ написан
  • Как сделать смену картинок на jquery с помощью радиокнопок?

    0xD34F
    @0xD34F Куратор тега JavaScript
    .images_box a {
      display: none;
    }
    
    .images_box a.active {
      display: inline;
    }

    const containerSelector = '.items-list-item-wrapper';
    const buttonSelector = '.items-list-item-colors input';
    const contentSelector = '.images_box a';
    const activeClass = 'active';
    
    
    // jquery, как вы и хотели
    $(containerSelector).on('change', buttonSelector, function(e) {
      $(contentSelector, e.delegateTarget)
        .removeClass(activeClass)
        .eq($(buttonSelector, e.delegateTarget).index(this))
        .addClass(activeClass);
    }).each((i, n) => $(buttonSelector, n).first().click());
    
    // или, к чёрту jquery
    document.querySelectorAll(containerSelector).forEach(n => {
      n.addEventListener('change', onChange);
      n.querySelector(buttonSelector).click();
    });
    
    function onChange({ target: t }) {
      if (t.matches(buttonSelector)) {
        const buttons = this.querySelectorAll(buttonSelector);
        const index = Array.prototype.indexOf.call(buttons, t);
        this.querySelectorAll(contentSelector).forEach((n, i) => {
          n.classList.toggle(activeClass, i === index);
        });
      }
    }
    Ответ написан
    Комментировать
  • Как скрыть блок при повторном нажатии на javascript?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Как заставить работать по-быстрому:
    function navFunction(id) {
      for (const n of document.querySelectorAll('.dropdown2-content')) {
        n.classList[n.id === id ? 'toggle' : 'remove']('show');
      }
    }

    Но вообще, тут многое можно изменить:

    Разметка - вырезать инлайновые обработчики клика и атрибуты id.

    Стили - будем плясать от корневых элементов (так удобнее; кроме того, если в будущем захотите стилизовать в "открытом" дропдауне что-то кроме контента, то не будет необходимости добавлять этим элементам классы, и, соответственно, не придётся переписывать код):

    .dropdown2 .dropdown2-content {
      display: none;
    }
    
    .dropdown2.show .dropdown2-content {
      display: block;
    }

    Код - вместо id будет смотреть на взаимное расположение элементов (переключаем класс у предка нажатой кнопки, у остальных удаляем):

    const containerSelector = '.dropdown2';
    const buttonSelector = `${containerSelector} .dropbtn2`;
    const activeClass = 'show';
    
    
    // делегирование, назначаем обработчик клика один раз для всех кнопок
    document.addEventListener('click', e => {
      const button = e.target.closest(buttonSelector);
      if (button) {
        document.querySelectorAll(containerSelector).forEach(function(n) {
          n.classList[n === this ? 'toggle' : 'remove'](activeClass);
        }, button.closest(containerSelector));
      }
    });
    
    // или, назначаем обработчик клика каждой кнопке индивидуально
    const onClick = function({ currentTarget: t }) {
      this.forEach((n, i) => n.classList[n.contains(t) ? 'toggle' : 'remove'](activeClass));
    }.bind(document.querySelectorAll(containerSelector));
    
    document.querySelectorAll(buttonSelector).forEach(n => {
      n.addEventListener('click', onClick);
    });
    Ответ написан
    Комментировать
  • Почему на другой странице снова хочет пароль?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что в sessionStorage хранятся строки. Т.е., реально сравниваются "true" и true.
    Ответ написан
    1 комментарий
  • Как сократить код используя цикл?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const inputSelector = '#icons_care';
    const checkboxSelector = '.check_care';
    const checkboxCheckedSelector = `${checkboxSelector}:checked`;
    const dataAttr = 'icon';
    const separator = ', ';

    $(document).on('change', checkboxSelector, () => {
      $(inputSelector).val($(checkboxCheckedSelector)
        .get()
        .map(n => $(n).data(dataAttr))
        .join(separator)
      );
    });
    
    // или
    
    document.addEventListener('change', e => {
      if (e.target.matches(checkboxSelector)) {
        const input = document.querySelector(inputSelector);
        const cb = document.querySelectorAll(checkboxCheckedSelector);
        input.value = Array.from(cb, n => n.dataset[dataAttr]).join(separator);
      }
    });
    Ответ написан
    3 комментария
  • Как оптимальнее при клике на кнопки изменять состояния связанных с ними блоков?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const buttonSelector = '.button';
    const blockSelector = '.div';
    const activeClass = 'red';
    
    function toggleBlock(blocks, buttons, button) {
      const index = Array.prototype.indexOf.call(buttons, button);
      blocks.forEach((n, i) => {
        n.classList[i === index ? 'toggle' : 'remove'](activeClass);
      });
    }
    
    
    // обработчик клика делегированный, назначается один раз
    document.addEventListener('click', e => {
      const button = e.target.closest(buttonSelector);
      if (button) {
        const blocks = document.querySelectorAll(blockSelector);
        const buttons = document.querySelectorAll(buttonSelector);
        toggleBlock(blocks, buttons, button);
      }
    });
    
    // или, назначаем обработчик клика каждой кнопке индивидуально
    const buttons = document.querySelectorAll(buttonSelector);
    const blocks = document.querySelectorAll(blockSelector);
    const onClick = e => toggleBlock(blocks, buttons, e.currentTarget);
    buttons.forEach(n => n.addEventListener('click', onClick));
    Ответ написан
    6 комментариев
  • Как добавить кнопки переключения по годам jquery ui datepicker?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А что, если надо было бы сделать 10 кнопок - вы бы под каждую написали отдельную функцию? Нет, так дела не делаются. Уберите id, добавьте кнопкам атрибут, который будет обозначать соответствующий год:

    <input class="date">
    <input class="date">
    <input class="date">

    const yearButton = year => `
      <button
        data-year="${year}"
        class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all"
      >${year}</button>
    `;
    
    $('.date').datepicker({
      showButtonPanel: true,
    }).each(function(i) {
      $(this).datepicker(
        'option',
        'currentText',
        `Today ${yearButton(2015 + i * 2)}${yearButton(2015 + i * 2 + 1)}`
      );
    });
    
    $(document).on('click', '[data-year]', function() {
      $.datepicker._curInst.input.datepicker('setDate', `01/01/${$(this).data('year')}`);
    });
    Ответ написан
    1 комментарий