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

    0xD34F
    @0xD34F Куратор тега JavaScript
    div.innerHTML +="qwe"

    Вас вводит в заблуждение оператор += - вам кажется, будто бы к содержимому div что-то там добавляется. Это не совсем так - содержимое div полностью перезаписывается. Соответственно, ранее добавленные элементы будут удалены и заменены новыми. А к новым элементам никаких обработчиков вы не привязываете - отсюда и отсутствие вывода в консоль.

    Если хотите, чтобы добавление текста не приводило к перезаписыванию содержимого элемента, выполняйте его с помощью методов insertAdjacentText или append. Или создавайте текстовый узел посредством createTextNode или Text и добавляйте его через appendChild.
    Ответ написан
    4 комментария
  • Как скопировать текст до определенного места?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Отрезайте от полного текста сколько надо, типа .slice(0, 3).

    Или вместо aux.select(); сделайте

    aux.focus();
    aux.setSelectionRange(0, 3);


    UPD. Вынесено из комментариев:

    нужно до плюса скопировать, там не всегда 3 символа может быть

    Можете найти '+' с помощью indexOf.

    Или регулярные выражения используйте: получите то, что перед плюсом (.match(/[^+]*/)), или удалите его и то, что после (.replace(/\+.*/, '')).
    Ответ написан
    2 комментария
  • Как определить что все асинхронные операции завершились?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Что мешает ещё раз применить Promise.all? Вместо вложенных forEach'ей будет как-то так:

    Promise.all(items.map((item, index) => axios.post(responses[index], item, config)))
    Ответ написан
    2 комментария
  • Как при клике на элемент добавить ему класс, а у всех соседей удалить?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где элементы находятся, что за элементы, и какой класс будем им добавлять/убирать:

    const container = document.querySelector('nav');
    const itemSelector = '.sidebar-item';
    const className = 'selected';

    Вариант раз, делегируем обработку клика контейнеру. При клике ищем элемент с нужным классом, снимаем класс, устанавливаем класс кликнутому:

    container.addEventListener('click', function(e) {
      const item = e.target.closest(itemSelector);
      if (item) {
        const activeItem = this.querySelector(`.${className}`);
        if (activeItem) {
          activeItem.classList.remove(className);
        }
    
        item.classList.add(className);
      }
    });

    Вариант два, тоже с делегированием. Перебираем все элементы, переключаем класс в зависимости от того, является ли текущий элемент кликнутым:

    container.addEventListener('click', e => {
      const item = e.target.closest(itemSelector);
      if (item) {
        for (const n of e.currentTarget.querySelectorAll(itemSelector)) {
          n.classList.toggle(className, n === item);
        }
      }
    });

    Вариант три, назначаем обработчик клика каждому элементу индивидуально, перебираем элементы аналогично предыдущему варианту:

    const items = container.querySelectorAll(itemSelector);
    const onClick = e => items.forEach(n => n.classList.toggle(className, n === e.currentTarget));
    items.forEach(n => n.addEventListener('click', onClick));
    Ответ написан
    Комментировать
  • Как изменить цвет шага в прогресс баре?

    0xD34F
    @0xD34F Куратор тега CSS
    <div id="progressBar"></div>
    
    <button>green</button>
    <button>red</button>
    <button>yellow</button>
    <button>magenta</button>
    <button>aqua</button>

    let percent = 0;
    const gradientParts = [];
    
    $('button').click(function() {
      if (percent < 100) {
        const color = $(this).text();
        percent++;
        gradientParts.push(`${color} ${percent - 1}%`, `${color} ${percent}%`);
        const gradient = gradientParts.concat(`#435C91 ${percent}%`, '#435C91 100%');
    
        $('#progressBar').css({
          background: `linear-gradient(to right, ${gradient.join(', ')})`,
        });
      }
    });

    https://jsfiddle.net/2yqzgeLb/
    Ответ написан
    Комментировать
  • Как, при выборе select точки на google карте, подвязать каждую точку к кнопке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Поскольку option'ы в select'е создаются на основе массива markers, то наверное в его элементы и следует добавить ссылки. В обработчике клика по текущему значению select'а получаем нужный элемент markers и... так?
    Ответ написан
    3 комментария
  • Возможно ли как-то заранее узнать сколько элементов в списке на которую пользователь хочет перенести элемент?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Список, в который будет помещён сортируемый элемент, доступен как event.target в обработчике события over.
    Ответ написан
    6 комментариев
  • Посчитать сумму элементов в кажом столбце двумерного массива?

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

    const rows = 3;
    const cols = 5;
    const max = 10;
    const arr =
      Array.from({ length: rows }, () =>
        Array.from({ length: cols }, () =>
          Math.random() * max | 0
        )
      );

    А вот суммы и вдоль, и поперёк, а где там у вас столбцы, и где строки - разбирайтесь сами:

    const sumRows = arr.map(n => n.reduce((acc, m) => acc + m, 0));
    const sumCols = (arr[0] || []).map((n, i) => arr.reduce((acc, m) => acc + m[i], 0));
    
    // или
    
    const [ sumRows, sumCols ] = arr.reduce((acc, n, i) => (
      n.forEach((m, j) => (acc[0][i] += m, acc[1][j] += m)),
      acc
    ), [ rows, cols ].map(n => Array(n).fill(0)));
    Ответ написан
    Комментировать
  • Как кастомизировать карту Google Map?

    0xD34F
    @0xD34F Куратор тега JavaScript
    интересуют только кастомные маркеры...

    свойство icon в настройках маркера

    ...и блоки с описанием этих маркеров

    infowindow
    Ответ написан
  • Как можно проапгрейдить скрипт?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вместо .label-text переключайте класс у максимально дальних не общих предков input'ов, т.е., у .thumb. Соответственно, стилизовать надо будет не .label-text.класс, а .класс .label-text. Зачем делать именно так? Потому что не придётся переписывать js-код, если вдруг вам завтра захочется кроме .label-text стилизовать ещё что-то, или решите изменить взаимное расположение элементов.

    Где input'ы находятся, что за input'ы, какой класс надо переключать:

    const containerSelector = '.thumb';
    const inputSelector = 'input[id^="input-"]';
    const activeClass = 'active';

    Переключать класс можете по-прежнему с помощью jquery:

    $(containerSelector).on('input', inputSelector, function(e) {
      $(e.delegateTarget).toggleClass(activeClass, !!this.value);
    });

    А можете начать осваивать чистый js:

    const onInput = ({ target: t, currentTarget: ct }) =>
      t.matches(inputSelector) && ct.classList.toggle(activeClass, !!t.value);
    
    document.querySelectorAll(containerSelector).forEach(n => {
      n.addEventListener('input', onInput);
    });
    Ответ написан
    1 комментарий
  • Как привязать игрока к карточки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А что это у вас там за цикл?.. Нет, не желаю этого знать. Делайте так: номер игрока равен номеру текущей карточки, а если игроки закончились, то берёте случайное значение. Т.е., заменяете

    for (let j = 1; j <= this.players; j++) { 
      this.card.dataset.playerId = j; // а тут устанавливаем playerId. Но он у меня постоянно одинаковый
    }

    на что-то вроде

    this.card.dataset.playerId = i <= this.players ? i : ((Math.random() * this.players | 0) + 1);
    Ответ написан
    4 комментария
  • Можно ли автоматически делать target blank для внешних ссылок?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Можно повесить обработчик click на корневой элемент: если целевым элементом является ссылка - отменяете действие по умолчанию и открываете новое окно вручную:

    <div id="app" @click="onClick">
      ...

    new Vue({
      el: '#app',
      methods: {
        onClick(e) {
          if (e.target.tagName === 'A') {
            e.preventDefault();
            window.open(e.target.getAttribute('href'));
          }
        },
        ...
      },
      ...
    });
    Ответ написан
    2 комментария
  • Как получить значение двух одинаковых по классам инпутов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const className = 'здесь должен быть класс ваших input\'ов';

    Получаем элементы:

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

    Собираем массив значений:

    const values = Array.from(inputs, n => n.value);
    
    // или
    
    const values = Array.prototype.map.call(inputs, n => n.value);
    
    // или
    
    const values = [];
    for (const n of inputs) {
      values.push(n.value);
    }
    
    // или
    
    const values = [];
    for (let i = 0; i < inputs.length; i++) {
      values[i] = inputs[i].value;
    }
    
    // или
    
    const values = (function get(i) {
      return inputs[i] ? [ inputs[i].value, ...get(i + 1) ] : [];
    })(0);
    Ответ написан
    Комментировать
  • Как объяснить сложение двух асинхронных потоков?

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

    next transaction (subscription) cannot start until the previous completes

    Хотите, чтобы было "независимо" - используйте merge вместо concat.
    Ответ написан
    Комментировать
  • Почему числа не складываются?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Замените $('.cart-window ul').each на $('.cart-window ul .item').each, а $(this).find('.item span').text() замените на $(this).find('span').text().

    А то сейчас вместо того, чтобы перебирать .item'ы, вы обрабатываете сразу весь список, разом получая содержимое всех .item span'ов - естественно, строки склеиваются.
    Ответ написан
  • Почему среднее значение разное?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Второй параметр в range - это количество элементов, а не конечное значение (как вам, по-видимому, показалось).

    То есть, в первом случае последовательность такая: 1, 2, 3, 4, 5. А во втором такая: 0, 1, 2, 3, 4. Соответственно, 15 / 5 = 3, 10 / 5 = 2, всё правильно.
    Ответ написан
    Комментировать
  • Почему не выводится результат из Observable?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Этот код вместо результата выводит undefined.

    Под "выводит" вы подразумеваете результат вызова console.log, да? Что ж, ничего ваш код не выводит - console.log не вызывается ни разу, undefined возникает в консоли потому, что последнее, что вы делаете - вызываете метод subscribe, который ничего не возвращает.

    Отсутствие вывода обусловлено пустотой массива result, а пуст он потому, что... Нет, не буду объяснять - разберитесь, как стрелочными функциями пользоваться, и найдите свои ошибки сами.
    Ответ написан
    3 комментария
  • Как обернуть картинку нужным кодом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кого надо обернуть:

    const elements = document.querySelectorAll('.news-full-text img');

    Оборачиваем:

    for (const n of elements) {
      const el = document.createElement('div');
      el.className = 'image';
      el.appendChild(document.createElement('div'));
      el.lastChild.className = 'image-social';
      el.lastChild.textContent = 'социальные кнопки';
      n.insertAdjacentElement('afterend', el);
      el.insertAdjacentElement('afterbegin', n);
    }

    или

    elements.forEach(n => n.outerHTML = `
      <div class="image">
        ${n.outerHTML}
        <div class="image-social">социальные кнопки</div>
      </div>
    `);
    Ответ написан
    1 комментарий
  • Как прописать логику спойлеру, чтобы он закрывался на второй клик вместе со всеми остальными?

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

    const containerSelector = '.spoiler-container';
    const headerSelector = '.spoiler-header';
    const contentSelector = '.spoiler-content';
    const activeClass = 'active';
    const toggleEffect = 'slideToggle'; // или fadeToggle, или toggle
    const hideEffect = 'slideUp'; // или fadeOut, или hide
    
    function toggle($containers, $container) {
      $containers
        .not($container)
        .removeClass(activeClass)
        .find(contentSelector)
        [hideEffect]();
    
      $container
        .toggleClass(activeClass)
        .find(contentSelector)
        [toggleEffect]();
    }

    Обработчик клика подключается блокам со спойлерами, но клики слушаться будут только по заголовкам:

    const $containers = $(containerSelector).on('click', headerSelector, e => {
      toggle($containers, $(e.delegateTarget));
    });

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

    $(document).on('click', `${containerSelector} ${headerSelector}`, e => {
      toggle($(containerSelector), $(e.target).closest(containerSelector));
    });
    Ответ написан
    1 комментарий