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

    0xD34F
    @0xD34F Куратор тега JavaScript
    const containerSelector = '.choose-buttons';
    const buttonSelector = '.btn';
    const activeClass = 'active';
    const maxActive = 3;

    $(containerSelector).on('click', buttonSelector, function(e) {
      const numActive = $(`${buttonSelector}.${activeClass}`, e.delegateTarget).length;
      const $this = $(this);
    
      if (numActive < maxActive || $this.hasClass(activeClass)) {
        $this.toggleClass(activeClass);
      }
    });
    
    // или
    
    document.querySelectorAll(containerSelector).forEach(n => {
      n.addEventListener('click', onClick);
    });
    
    function onClick(e) {
      const button = e.target.closest(buttonSelector);
      if (button) {
        const active = [...this.querySelectorAll(`${buttonSelector}.${activeClass}`)];
        if (active.length < maxActive || active.includes(button)) {
          button.classList.toggle(activeClass);
        }
      }
    }
    Ответ написан
  • Как удалить класс, если scrollTop === 0?

    0xD34F
    @0xD34F Куратор тега JavaScript
    navbar.classList.toggle('fixed', (lastScroll - scrollTop > 0) && scrollTop);
    Ответ написан
    Комментировать
  • Почему в jQueryUI Datepicker событие onSelect, не видит setDate?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Во-первых,

    событие не срабатывает

    - так не говорят, это безграмотно. События никогда не срабатывают. Срабатывают обработчики событий.

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

    Если откроете документацию, то увидите, что там вам никто не обещает вызов onSelect при вызове setDate. Так что формальный ответ на ваш вопрос прост - ну, вот так datepicker устроен. Отвечая на незаданный, но подразумевающийся вами вопрос (как добиться срабатывания onSelect при вызове setDate) - можно соорудить костыль, подменив метод setDate, где будет вызываться исходный метод, а затем выполняться какое-то действие, которое приведёт к вызову onSelect. Например:

    const oldSetDate = $.datepicker._setDate;
    $.datepicker._setDate = function(...args) {
      oldSetDate.apply(this, args);
      setTimeout(() => args[0].input.find('.ui-datepicker-current-day').click());
    };

    https://jsfiddle.net/7zge4jv9/1/

    UPD. Заявка на данный функционал появилась ещё семь лет назад, но так ничего и не сделали. И не сделают уже, надо полагать.
    Ответ написан
  • Как сделать счетчик со сменой цвета активного элемента по клику?

    0xD34F
    @0xD34F Куратор тега JavaScript
    p.process-block__stage-number.active I
    p.process-block__stage-number II
    p.process-block__stage-number III
    p.process-block__stage-number IV
    
    button.process-block__btn(data-change=-1)
      span
        b prev
    button.process-block__btn(data-change=+1)
      span
        b next

    document.addEventListener('click', function(e) {
      const button = e.target.closest('[data-change]');
      if (button) {
        const blocks = [...document.querySelectorAll('.process-block__stage-number')];
        let active = blocks.findIndex(n => n.classList.contains('active'));
    
        blocks[active].classList.remove('active');
        active = Math.max(0, Math.min(blocks.length - 1, active + +button.dataset.change));
        blocks[active].classList.add('active');
      }
    });

    https://codepen.io/anon/pen/bZryZQ?editors=1010
    Ответ написан
    3 комментария
  • Как сделать promise-заглушку вместо ajax-запроса к серверу?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getData = (delay = 1000) =>
      new Promise(r => setTimeout(r, delay, сюда подставляете данные));
    Ответ написан
    Комментировать
  • Как задать фон первому элементу меню?

    0xD34F
    @0xD34F Куратор тега JavaScript
    проблема в том, что при клике по какому-либо элементу подМЕНЮ, первый, элемент который задавался по умолчанию не сбрасывает стиль

    Всё-таки стиль сбрасывается. А потом снова устанавливается. Потому что из-за всплытия события срабатывает обработчик клика основного меню. Отменяйте всплытие в обработчике клика подменю, и всё будет OK:

    $('ul#topnav li span a').click(function(e) {
      e.stopPropagation();
      ...
    Ответ написан
    1 комментарий
  • Почему при клике обработчик события срабатывает два раза?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что клик на лейбл вызывает клик на инпуте (так лейблы устроены, могут вызывать клик на других элементах), а так как инпут находится внутри лейбла, событие при всплытии заставляет обработчик клика сработать ещё раз.

    Какие есть варианты исправить ситуацию:
    1. Вешайте обработчик клика на инпут вместо лейбла
    2. Проверяйте целевой элемент, если не инпут - ничего делать не надо
    3. Обрабатывайте вместо click событие change
    Ответ написан
    Комментировать
  • Как вернуть ключ многомерного массива с максимальным числом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const [ key ] = Object
      .entries(data)
      .reduce((max, [ k, { Number_of_Something: v } ]) => {
        return max[1] > v ? max : [ k, v ];
      }, [ null, -Infinity ]);

    или

    const key = (Object
      .entries(data)
      .sort((a, b) => b[1].Number_of_Something - a[1].Number_of_Something)
      .shift() || [ null ])
      .shift();

    или

    let key = null;
    let max = -Infinity;
    for (const k in data) {
      if (data.hasOwnProperty(k) && data[k].Number_of_Something > max) {
        key = k;
        max = data[k].Number_of_Something;
      }
    }

    или

    const max = Math.max(...Object.values(data).map(n => n.Number_of_Something));
    const key = Object.keys(data).find(k => data[k].Number_of_Something === max) || null;
    Ответ написан
  • Как из массива по клику получать на вывод по 2 картинки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    <div class="out"></div>
    <button class="btn">click me</button>

    const images = [ '...', '...', /* ... */ ];
    const SHOW_MORE = 2;
    
    document.querySelector('.btn').addEventListener('click', e => {
      document.querySelector('.out').insertAdjacentHTML('beforeend', images
        .splice(0, SHOW_MORE)
        .map(n => `<div class="outImg"><img src="${n}"></div>`)
        .join('')
      );
    
      e.target.disabled = !images.length;
    });
    Ответ написан
    Комментировать
  • Что неправильно с кодом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('ur_login')

    Круто. Новый тэг появился.

    $('ur_password')

    Два новых тэга.

    только начал учить AJAX и PDO

    Начните ещё учить селекторы. Первым делом - погуглите, как обращаться к элементу по id.
    Ответ написан
    4 комментария
  • Вывести данные с помощью this?

    0xD34F
    @0xD34F Куратор тега JavaScript
    success: (data) => {
      $(this).toggleClass('like-active like_click').find('.like_count').html(data);
    },
    Ответ написан
    Комментировать
  • Как с помощью JS вызвать событие change и убрать галочку на чекбоксе?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вариант раз - вызвать у элемента метод click: checkbox.click();.

    Вариант два - установить новое значение checked и отправить элементу событие change:

    checkbox.checked = /* сюда пишем true или false */;
    checkbox.dispatchEvent(new Event('change'));
    Ответ написан
    Комментировать
  • Как реализовать калькулятор?

    0xD34F
    @0xD34F Куратор тега JavaScript
    1. eval
    2. рекурсивный спуск
    3. откажитесь от выражений, и имитируйте реальный карманный калькулятор - при нажатии на сложение/умножение/... текущее число запоминается, выбранная операция запоминается, поле ввода очищается (или, если уже есть ранее запомненные число и операция, производится соответствующее вычисление и вывод результата)
    Ответ написан
  • Как сравнить данные в таблице и выделить цветом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    О какой таблице идёт речь:

    const table = document.querySelector('.table-price table');

    Для выделения используем классы:

    .highlight-min {
      color: green;
      font-weight: bold;
    }
    
    .highlight-max {
      color: red;
      font-weight: bold;
    }

    Находим минимум:

    table.querySelectorAll('tr').forEach(n => {
      const td = Array
        .from(n.querySelectorAll('td:not(.logo-table)'), m => [ m, +m.innerText.match(/\d+/) ])
        .sort((a, b) => a[1] - b[1])[0][0];
    
      td.classList.add('highlight-min');
    });

    Но что если искомое значение представлено в нескольких экземплярах? Выделяем все максимумы:

    for (const { cells: [ , ...cells ] } of table.rows) {
      const [ tds ] = cells.reduce((max, n) => {
        const val = parseInt(n.textContent);
        if (val > max[1]) {
          max = [ [], val ];
        }
        if (val === max[1]) {
          max[0].push(n);
        }
        return max;
      }, [ [], -Infinity ]);
    
      tds.forEach(n => n.classList.add('highlight-max'));
    }

    https://jsfiddle.net/72msenta/
    Ответ написан
    Комментировать
  • Как получить список id элементов, имея их общий класс?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const className = 'класс элементов, чьи id вам надо получить';

    Как получить элементы, зная их класс:

    const elems = document.querySelectorAll(`.${className}`);
    // или
    const elems = document.getElementsByClassName(className);

    Как извлечь из элемента его id:

    const getId = el => el.id;
    // или
    const getId = el => el.getAttribute('id');
    // или
    const getId = el => el.attributes.id.value;

    Как собрать массив id:

    const ids = Array.from(elems, getId);
    
    // или
    
    const ids = Array.prototype.map.call(elems, getId);
    
    // или
    
    const ids = [];
    for (const n of elems) {
      ids.push(getId(n));
    }
    
    // или
    
    const ids = [];
    for (let i = 0; i < elems.length; i++) {
      ids[i] = getId(elems[i]);
    }
    
    // или
    
    const ids = (function get(i) {
      return elems[i] ? [ getId(elems[i]), ...get(i + 1) ] : [];
    })(0);
    Ответ написан
    Комментировать
  • Как удалить объект из массива с одинаковым id и оставить тот, где есть доп свойство?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const result = Object.values(arr.reduce((acc, n) => (
      acc[n.id] = n.checked ? n : (acc[n.id] || n),
      acc
    ), {}));

    или, с сохранением порядка:

    const result = arr.reduce((acc, n) => {
      const i = acc.findIndex(m => m.id === n.id);
      if (!~i || (!acc[i].checked && n.checked)) {
        acc.push(n);
        if (~i) {
          acc.splice(i, 1);
        }
      }
      return acc;
    }, []);
    
    // или
    
    const result = Object
      .values(arr.reduce((acc, n, i) => (
        (!acc[n.id] || (!acc[n.id][0].checked && n.checked)) && (acc[n.id] = [ n, i ]),
        acc
      ), {}))
      .sort((a, b) => a[1] - b[1])
      .map(n => n[0]);
    Ответ написан
    3 комментария
  • Как скрыть дубликаты элементов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    [...document.querySelectorAll('.buy > i')]
      .filter((n, i, a) => i !== a.findIndex(m => m.innerText === n.innerText))
      .forEach(n => n.parentNode.style.display = 'none');

    или

    const grouped = Array
      .from(document.querySelectorAll('.buy > i'), n => [ n.parentNode, n.innerText ])
      .reduce((acc, n) => ((acc[n[1]] = acc[n[1]] || []).push(n[0]), acc), {});
    
    Object.values(grouped).forEach(n => n.forEach((m, i) => m.hidden = !!i));

    или

    .hidden {
      display: none;
    }

    const unique = new Set();
    
    for (const n of document.querySelectorAll('.buy > i')) {
      if (unique.has(n.innerText)) {
        n.parentNode.classList.add('hidden');
      } else {
        unique.add(n.innerText);
      }
    }
    Ответ написан
    Комментировать
  • Как отфильтровать массив, чтобы у элементов значения определённого свойства не повторялись?

    0xD34F
    @0xD34F Куратор тега JavaScript
    people.filter((n, i, a) => n.country && i === a.findIndex(m => m.country === n.country))

    или

    people.filter((n, i, a) => n.country && n === a.find(m => m.country === n.country))

    или

    people.filter(function({ country: n }) {
      return n && !(this[n] = this.hasOwnProperty(n));
    }, {})

    или

    Object.values(people.reduce((acc, n) => (n.country && (acc[n.country] = n), acc), {}))

    или

    [...people.reduce((acc, n) => n.country ? acc.set(n.country, n) : acc, new Map).values()]

    или

    Array.from(
      new Set(people.map(n => n.country).filter(Boolean)),
      n => people.find(m => m.country === n)
    )
    Ответ написан
    1 комментарий
  • Как показать/скрыть блок при совпадении нескольких условий?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const block = document.querySelector('.block');
    const inputSelector = 'input[type="number"]';

    const toggleBlock = () =>
      block.style.display = Array
        .from(document.querySelectorAll(inputSelector))
        .some(n => n.value && +n.value > +n.min)
          ? 'block'
          : 'none';
    
    document.addEventListener('input', e => e.target.matches(inputSelector) && toggleBlock());
    toggleBlock();
    
    // или
    
    const inputs = document.querySelectorAll(inputSelector);
    const toggleBlock = () =>
      block.hidden = Array.prototype.every.call(
        inputs,
        n => !n.value || +n.value <= +n.min
      );
    
    inputs.forEach(n => n.addEventListener('input', toggleBlock));
    toggleBlock();
    Ответ написан
  • Как выполнять различные действия в зависимости от содержимого массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    if ( typeof arr[i] === 'number' ) {
     		x*= arr[i];

    А что если arr[i + 1] окажется строкой? Сначала надо проверить всё, а уже потом вычислять (если потребуется) объединённое значение:

    function bullshit(arr) {
      if (arr.every(n => typeof n === 'number')) {
        return arr.reduce((acc, n) => acc * n, 1);
      }
    
      if (arr.every(n => typeof n === 'string')) {
        return arr.join('');
      }
    
      return null;
    }
    
    
    bullshit([ 1, 2, 3 ]) // 6
    bullshit([ 'a', 'b', 'c' ]) // 'abc'
    bullshit([ 1, '!' ]) // null

    или

    function bullshit(arr) {
      const count = arr.reduce((acc, n) => {
        const type = typeof n;
        acc[type] = (acc[type] || 0) + 1;
        return acc;
      }, {});
    
      switch (arr.length) {
        case count.number: return arr.reduce((acc, n) => acc * n, 1);
        case count.string: return arr.join('');
        default: return null;
      }
    }
    Ответ написан
    1 комментарий