Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как на js или jq кликнуть на первые 100 элементов HTML (начиная с верха страницы) id которых начинается на "oOR"?

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

    const selector = '[id^="oOR"]';
    const clickCount = 100;

    Кликаем:

    $(selector).slice(0, clickCount).click();
    
    // или
    
    [...document.querySelectorAll(selector)].slice(0, clickCount).forEach(n => n.click());

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

    из-за "одновременного" клика все виснет

    Может подскажете конструкцию с .delay() (или чем то аналогичным)

    Функция, с помощью которой можно обрабатывать массивоподобные объекты по частям с задержкой:

    function chunkedAndDelayed(data, delay, chunkSize, onChunk) {
      const getChunk = (data.slice || Array.prototype.slice).bind(data);
    
      (function nextChunk(i) {
        if (i < data.length) {
          onChunk(getChunk(i, i + chunkSize));
          setTimeout(nextChunk, delay, i + chunkSize);
        }
      })(0);
    }

    C каким интервалом и по сколько за раз надо кликать:

    const delay = 500;
    const clickChunkSize = 5;

    Кликаем:

    chunkedAndDelayed(
      $(`${selector}:lt(${clickCount})`),
      delay,
      clickChunkSize,
      $elems => $elems.click()
    );
    
    // или
    
    chunkedAndDelayed(
      Array.prototype.slice.call(document.querySelectorAll(selector), 0, clickCount),
      delay,
      clickChunkSize,
      elems => elems.forEach(n => n.click())
    );
    Ответ написан
    2 комментария
  • Как разбить ссылку на название файла и адрес?

    0xD34F
    @0xD34F Куратор тега JavaScript
    JS:

    const [ , path, file ] = /(.+\/)([^\/]+)$/.exec(str);
    
    // или
    
    const i = str.lastIndexOf('/') + 1;
    const file = str.slice(i);
    const path = str.slice(0, i);
    
    // или
    
    const parts = str.split(/(\/)/);
    const file = parts.pop();
    const path = parts.join('');

    PHP:

    preg_match('~^(.+\/)([^\/]+)$~', $str, $matches);
    list($path, $file) = array_slice($matches, 1);
    
    // или
    
    $i = strrpos($str, '/') + 1;
    $file = substr($str, $i);
    $path = substr($str, 0, $i);
    
    // или
    
    $parts = preg_split('~(?<=\/)~', $str);
    $file = array_pop($parts);
    $path = implode('', $parts);
    Ответ написан
    Комментировать
  • Задача с селектором, как решить?

    0xD34F
    @0xD34F Куратор тега JavaScript
    <select id="country"></select>
    <select id="сity"></select>
    <p></p>

    const data = {
      'Франция': [ 'Париж', 'Марсель', 'Лион' ],
      'США': [ 'Вашингтон', 'Чикаго', 'Фарго' ],
      'Италия': [ 'Рим', 'Милан', 'Неаполь' ],
    };
    
    const country = document.querySelector('#country');
    const city = document.querySelector('#сity');
    const p = document.querySelector('p');
    
    country.addEventListener('change', e => {
      setSelectOptions(city, data[e.target.value]);
    });
    
    city.addEventListener('change', () => {
      p.innerText = [ country.value, city.value ].join(', ');
    });
    
    setSelectOptions(country, Object.keys(data));
    
    
    function setSelectOptions(selectEl, optionsData) {
      selectEl.innerHTML = optionsData.map(n => `<option>${n}</option>`).join('');
      selectEl.dispatchEvent(new Event('change'));
    }
    Ответ написан
    1 комментарий
  • Как сделать один обработчик для всех менюшек?

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

    1. Если клик был за пределами какого-либо выпадающего меню - закрываем их все
    2. Если клик был по кнопке открытия - открываем соответствующее ей меню

    const cardSelector = '.post';
    const buttonSelector = '.post > img';
    const menuSelector = '.post-info';
    const activeClass = 'active';
    
    document.addEventListener('click', ({ target: t }) => {
      if (!t.closest(menuSelector)) {
        document.querySelectorAll(menuSelector).forEach(n => n.classList.remove(activeClass));
      }
    
      if (t = t.closest(buttonSelector)) {
        t.closest(cardSelector).querySelector(menuSelector).classList.add(activeClass);
      }
    });
    Ответ написан
    2 комментария
  • В To-Do приложении таски отмечаются через один. Почему?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что при каждом создании нового пункта вешается дополнительный обработчик клика на все пункты списка. В результате на чётных пунктах срабатывает чётное количество обработчиков - класс goal-check выставляется и тут же снимается.

    UPD. Обработчики кликов на .goal и .delete надо вешать один раз, применяя делегирование:

    $('.todo-task').on('click', '.delete', function() {
      $(this).parent().remove();   
    });
    
    $('.todo-task').on('click', '.goal', function() {
      $(this).toggleClass('goal-check');
    });
    Ответ написан
    3 комментария
  • Как пересчитать дочерние узлы в DOM при этом добавляя и удаляя классы?

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

    Кому, какой класс и с каким интервалом времени надо переключать:

    const elements = document.querySelector('#presentation').children;
    const className = 'animation';
    const delay = 1000;

    Переключаем:

    let i = elements.length - 1;
    
    setInterval(() => {
      elements[i].classList.remove(className);
      i = (i + 1) % elements.length;
      elements[i].classList.add(className);
    }, delay);

    или

    (function next(i) {
      elements.item(i).classList.toggle(className, false);
      i = -~i % elements.length;
      elements.item(i).classList.toggle(className, true);
      setTimeout(next, delay, i);
    })(~-elements.length);
    Ответ написан
    1 комментарий
  • Как не обрабатывать клик по некоторым из вложенных элементов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Чьи клики не нужны:

    const selector = '.tr-class input[type="checkbox"]';

    Можно добавить нежелательным элементам обработчик, где будет останавливаться всплытие события:

    document.querySelectorAll(selector).forEach(function(n) {
      n.addEventListener('click', this);
    }, e => e.stopPropagation());

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

    for (const n of document.querySelectorAll('.tr-class')) {
      n.addEventListener('click', onClick);
    }
    
    function onClick(e) {
      if (e.target.matches(selector)) {
        return;
      }
    
      // ...
    }
    Ответ написан
    1 комментарий
  • Как можно короче записать тернарное условие?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Можно короче без тернарного оператора:

    myVariable && (myVariable - 35)

    Проверяем, действительно ли будем получать одно и то же:

    [100, 0, null, '', true, false, 'gdfsg'].map(n => [n ? n - 35 : n, n && (n - 35)]);
    /*
    0:(2) [65, 65]
    1:(2) [0, 0]
    2:(2) [null, null]
    3:(2) ["", ""]
    4:(2) [-34, -34]
    5:(2) [false, false]
    6:(2) [NaN, NaN]
    */

    Вроде похоже на правду.

    UPD. Можно с функцией, так длинное имя переменной будет использовано всего один раз:

    (n => n && (n - 35))(myVariable)
    Ответ написан
    Комментировать
  • Как решить проблему с датой для datepicker при чтении параметра из URL?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Как решить эту проблему?

    А что за проблема-то? День и месяц перепутаны - должно быть 6 сентября? Используйте moment.js. Можно задавать произвольный формат:

    moment('06.09.2017 16:16', 'DD-MM-YYYY HH:mm')

    Ну или вручную меняйте их местами, например:

    new Date('06.09.2017 16:16'.replace(/(\d+)\.(\d+)\.(\d+)/, '$3-$2-$1'))
    Ответ написан
    Комментировать
  • Почему не срабатывает триггер?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Не срабатывает потому, что обработчик события установлен не через jQuery. Отсюда и решение - создавать и отправлять событие вручную.

    Вместо $('select').val('ru').trigger('click'); пишем так:

    $('select').val('ru')[0].dispatchEvent(new Event('change'));
    Ответ написан
    1 комментарий
  • Как реализовать множественное наследование свойств и методов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Насколько я понял, вам нужно что-то такое:

    function C() {
      A.call(this);
      B.call(this);
    }
    Object.assign(C.prototype, A.prototype, B.prototype);
    Ответ написан
    1 комментарий
  • Нужно послать значение из атрибута data-value. Как правильно обрабатывать данные пришедшие Ajax-ом в php скрипке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Почему нужное значение лежит в ключе?

    Может, потому что вы данные как-то не так отправляете? Например, пишете data: page вместо

    data: { page /* или как оно там должно называться? */: page }
    Ответ написан
    Комментировать
  • Как выбрать несколько случайных неповторяющихся элементов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Откуда, куда, что и в каком количестве надо копировать:

    const sourceSelector = '#a';
    const targetSelector = '#b';
    const itemSelector = 'li';
    const count = 3;

    Вспомогательная функция - вырезание из массива случайного элемента:

    const random = arr => arr.splice(Math.random() * arr.length | 0, 1)[0];

    Копируем:

    $(sourceSelector).on('click', itemSelector, function() {
      const items = $(this).siblings().clone().get();
      $(targetSelector).html([...Array(count)].map(random.bind(null, items)));
    });
    
    // или
    
    const source = document.querySelector(sourceSelector);
    const target = document.querySelector(targetSelector);
    source.addEventListener('click', ({ target: t }) => {
      if (t = t.closest(itemSelector)) {
        const items = [...source.querySelectorAll(itemSelector)].filter(n => n !== t);
        target.innerHTML = '';
        target.append(...Array.from(
          { length: Math.min(items.length, count) },
          () => random(items).cloneNode(true)
        ));
      }
    });

    Похоже на то, что вам надо?

    UPD. Как-то сразу не заметил:

    если в списке всего три элемента - все три и выводятся

    Сначала получаем всё, если кликнутый не нужен, вырезаем его:

    const items = $(itemSelector, sourceSelector).clone().get();
    if (items.length > count) {
      items.splice($(this).index(), 1);
    }
    
    // или
    
    const items = [...source.querySelectorAll(itemSelector)];
    if (items.length > count) {
      items.splice(items.indexOf(t), 1);
    }
    Ответ написан
    1 комментарий
  • Как сделать отсчет по 0,01 javascript?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $({ number: +$('.number').text() }).animate({ number: 5 }, {
      duration: 5000, 
      easing: 'linear',
      step: updateNumber,
      complete: updateNumber,
    });
    
    function updateNumber() {
      $('.number').text((+this.number).toFixed(2));
    }


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

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

    <div id="list">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
      <div class="item">6</div>
    <div>

    const $items = $('#list .item').click(function() {
      console.log($items.not(this).slice(0, 3).toArray());
    });
    
    // или
    
    $('#list').on('click', '.item', function() {
      console.log($(this).siblings().slice(0, 3).get());
    });
    Ответ написан
    1 комментарий
  • Заполнения массива на Javascript?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function createArr(size) {
      const arr = [...Array(size)].map(() => Array(size).fill(0));
    
      const mid = (size / 2) | 0;
      arr.forEach((n, i) => {
        n[i] = n[size - i - 1] = 1;
        // если размер чётный, непонятно, где выставлять единицы, так что выставляем только для нечётных
        if (size & 1) {
          arr[mid][i] = n[mid] = 1;
        }
      });
      // хотя, конечно, есть вариант ставить по два вертикальных и горизонтальных ряда единиц
      /*
      const mid = (size - 1) / 2;
      arr.forEach((n, i) =>
        n[i] =
        arr[mid | 0][i] =
        arr[Math.ceil(mid)][i] =
        n[mid | 0] =
        n[Math.ceil(mid)] =
        n[size - i - 1] =
      1);
      */
    
      return arr;
    }

    Оценить результат работы можно так, например:

    console.log(createArr(21).map(n => n.join('')).join('\n'));

    Выведет такое вот чудище:

    100000000010000000001
    010000000010000000010
    001000000010000000100
    000100000010000001000
    000010000010000010000
    000001000010000100000
    000000100010001000000
    000000010010010000000
    000000001010100000000
    000000000111000000000
    111111111111111111111
    000000000111000000000
    000000001010100000000
    000000010010010000000
    000000100010001000000
    000001000010000100000
    000010000010000010000
    000100000010000001000
    001000000010000000100
    010000000010000000010
    100000000010000000001
    Ответ написан
    Комментировать
  • Как получить ссылку сайта без указания текущего php файла?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.split('/').slice(0, -1).join('/') + '/'

    или

    str.split(/(\/)/).slice(0, -1).join('')

    или

    str.slice(0, str.lastIndexOf('/') + 1)

    или

    str.match(/.+\//)[0]

    или

    str.replace(/[^\/]+$/, '')
    Ответ написан
    Комментировать
  • Как сделать математический расчет на чекбоксах и jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Делаете функцию, где обходите все элементы, от состояния которых сумма зависит, считаете сумму. Подключаете эту функцию в качестве обработчика событий, возникающих при изменении состояния элементов. Например.
    Ответ написан
    Комментировать
  • Почему стили не применяются к второму элементу?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А что такое scrollRight? Я такой функции не знаю. jQuery - тоже. Вот вам и причина, почему стили не применяются - ошибка "scrollRight is not a function".
    Ответ написан
    3 комментария