Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как сгенерировать случайное число, содержащее две единицы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const rand = (max, min = 0) =>
      Math.floor(Math.random() * (max - min)) + min;
    
    const createArr = ({
      length,
      digit,
      digitCount,
      max = Number.MAX_SAFE_INTEGER,
    }) =>
      Array.from({ length }, function() {
        const digits = `${rand(max, 10 ** (digitCount - !!digit))}`
          .replace(RegExp(digit, 'g'), (_, i) => this[rand(this.length, +!(i || digit))])
          .split('');
    
        const index = [...digits.keys()].slice(+!digit);
    
        for (let i = 0; i < digitCount; i++) {
          digits.splice(index.splice(rand(index.length), 1)[0], 1, digit);
        }
    
        return +digits.join('');
      }, [...Array(10).keys()].filter(n => n !== digit));

    const arr = createArr({
      length: 5,
      digit: 1,
      digitCount: 2,
      max: 10 ** 5,
    });
    Ответ написан
    Комментировать
  • Как заполнить таблицу, имея массив с данными?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const tbody = document.querySelector('#test tbody');
    const keys = [ 'name.firstName', 'name.lastName', 'about', 'eyeColor' ].map(n => n.split('.'));
    const getVal = (obj, keys) => keys.reduce((p, c) => p != null ? p[c] : p, obj);

    for (const n of data) {
      keys.forEach(function(k) {
        this.insertCell().textContent = getVal(n, k);
      }, tbody.insertRow());
    }
    
    // или
    
    tbody.insertAdjacentHTML('beforeend', data
      .map(n => `
        <tr>${keys.map(k => `
          <td>${getVal(n, k)}</td>`).join('')}
        </tr>`)
      .join('')
    );
    Ответ написан
    Комментировать
  • Как все элементы привести к денежному типу?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Как подсказывает документация, для этого есть метод multiple:

    AutoNumeric.multiple('.numeric', {
      decimalCharacter : '.',
      digitGroupSeparator : ' ',
    })
    Ответ написан
    Комментировать
  • Как сделать бесконечный цикл переворачивания картинок?

    0xD34F
    @0xD34F Куратор тега CSS
    <div id="images">
      <img src="https://placehold.co/200x200/FF0000/FFFFFF/png">
      <img src="https://placehold.co/200x200/00FF00/000000/png">
      <img src="https://placehold.co/200x200/0000FF/FFFFFF/png">
    </div>

    #images img {
      transition: transform 0.7s;
    }

    Зациклить анимацию разворота можно через js:

    .rotate {
      transform: rotateY(180deg);
    }

    const toggleRotate = el => el.classList.toggle('rotate');
    
    document.querySelectorAll('#images img').forEach((n, i) => {
      setTimeout(setInterval, 300 * i, toggleRotate, 2000, n);
    });

    Или через css:

    #images img {
      animation: rotate 4s infinite;
    }
    
    #images img:nth-child(1) { animation-delay:   0s; }
    #images img:nth-child(2) { animation-delay: 0.3s; }
    #images img:nth-child(3) { animation-delay: 0.6s; }
    
    @keyframes rotate {
      0%, 75%, 100% {
        transform: rotateY(0deg);
      }
      25%, 50% {
        transform: rotateY(180deg);
      }
    }
    Ответ написан
    Комментировать
  • Как отсортировать массив объектов по массиву значений определённого свойства?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сортируем существующий массив:

    messages.sort((a, b) => {
      [ a, b ] = [ a, b ].map(n => sortableLanguages.indexOf(n.language));
      return a === -1 ? 1 : b === -1 ? -1 : a - b;
    });

    Собираем отсортированный новый:

    const sorted = (arr, key) => arr
      .map(n => [ n, key(n) ])
      .sort((a, b) => a[1] - b[1])
      .map(n => n[0]);
    
    const order = Object.fromEntries(sortableLanguages.map((n, i) => [ n, i + 1 ]));
    const sortedMessages = sorted(messages, n => order[n.language] || Number.MAX_SAFE_INTEGER);

    или

    function sorted(arr, order, key) {
      const ordered = new Map(order.map(n => [ n, [] ]));
      const unordered = [];
      arr.forEach(n => (ordered.get(key(n)) || unordered).push(n));
      return [].concat(...ordered.values(), unordered);
    }
    
    const sortedMessages = sorted(messages, sortableLanguages, n => n.language);
    Ответ написан
    1 комментарий
  • Как добавить класс при клике на чистом javascript?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const buttonSelector = '.one';
    const contentSelector = '.two';
    const className = 'three';

    Сколько таких пар элементов? Если одна:

    document.querySelector(buttonSelector).addEventListener('click', () => {
      document.querySelector(contentSelector).classList.toggle(className);
    });

    Несколько:

    document.addEventListener('click', e => {
      const button = e.target.closest(buttonSelector);
      if (button) {
        const index = [...document.querySelectorAll(buttonSelector)].indexOf(button);
        document.querySelectorAll(contentSelector)[index].classList.toggle(className);
      }
    });
    
    // или
    
    const buttons = document.querySelectorAll(buttonSelector);
    const contents = document.querySelectorAll(contentSelector);
    
    buttons.forEach(n => n.addEventListener('click', onClick));
    
    function onClick(e) {
      const index = Array.prototype.indexOf.call(buttons, e.currentTarget);
      contents[index].classList.toggle(className);
    }
    Ответ написан
    Комментировать
  • Почему не работает проверка сложности пароля?

    0xD34F
    @0xD34F Куратор тега JavaScript
    for (let i = 0; i < password.length; i + 1) {

    если запустить код то страница крашнется, codesandbox на счет этого говорит что циклов слишком много

    Ну да, i + 1 - счётчик не меняет своего значения, цикл получается бесконечным.

    Должно быть или i += 1 или i++.

    return pass;

    Наверное, всё-таки должно быть return text.
    Ответ написан
    2 комментария
  • Как удалить подмассив из массива, если в подмассиве только пустые строки?

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

    const mustStay = arr => arr.some(n => n !== '');

    Удаляем неподходящие:

    for (let i = 0; i < arr.length; i++) {
      if (!mustStay(arr[i])) {
        for (let j = i--; ++j < arr.length; arr[j - 1] = arr[j]) ;
        arr.pop();
      }
    }
    
    // или
    
    arr.reduceRight((_, n, i, a) => mustStay(n) || a.splice(i, 1), null);
    
    // или
    
    arr.splice(0, arr.length, ...arr.filter(mustStay));
    
    // или
    
    arr.length -= arr.reduce((acc, n, i, a) => (
      a[i - acc] = n,
      acc + !mustStay(n)
    ), 0);
    Ответ написан
    4 комментария
  • Как передавать функции только индекс от массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Есть вариант воспользоваться методом keys для получения итератора, отдающего индексы (доступен как для NodeList, так и для массивов), который затем можно развернуть в массив с помощью spread или Array.from или просто перебрать через for of:

    [...divs.keys()].forEach(i => console.log(i));
    
    // или
    
    console.log(Array.from(divs.keys(), i => i * 100));
    
    // или
    
    for (const i of divs.keys()) {
      console.log(i);
    }
    Ответ написан
    2 комментария
  • Как добавить класс элементам, значение определённого атрибута которых присутствует в массиве?

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

    const key = 'i';
    const attr = `data-${key}`;
    const values = [ 'qwe', 'asd', 'zxc' ];
    const className = 'класс';

    Просто добавляем класс кому надо:

    document
      .querySelectorAll(values.map(n => `[${attr}="${n}"]`))
      .forEach(n => n.classList.add(className));

    Или, также у элементов с неподходящим значением атрибута класс удаляем:

    for (const n of document.querySelectorAll(`[${attr}]`)) {
      n.classList.toggle(className, values.includes(n.dataset[key]));
    }
    Ответ написан
    Комментировать
  • Как обернуть кусок текста в span?

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

    Хватаем текстовое содержимое элемента, с помощью регулярного выражения находим тот кусок, который надо обернуть в span, выполняем замену, записываем результат обратно в элемент, но уже не как текст, а как разметку:

    document.querySelectorAll('.scroll_list li').forEach(n => {
      n.innerHTML = n.textContent.replace(/\d+ шт./, '<span>$&</span>');
    });
    
    // или
    
    for (const n of document.querySelector('.scroll_list').children) {
      n.innerHTML = n.innerText.replace(/\S+ \S+$/, m => `<span>${m}</span>`);
    }

    ...или PHP

    Вот здесь точно никаких "обернуть" не надо. Разберитесь, где у вас формируется разметка страницы, и измените этот код так, чтобы нужный вам span создавался сразу.
    Ответ написан
    2 комментария
  • Как подсветить элемент?

    0xD34F
    @0xD34F Куратор тега JavaScript
    HTML
    <p>
      <b>Text</b>
      <input type="text" id="text">
      <b>Color</b>
      <input type="text" id="color">
    </p>
    <button id="create">create</button>
    <button id="update">update</button>
    <button id="del">delete</button>
    <ul id="items"></ul>

    CSS
    .active {
      border: 2px solid black;
    }

    JS
    const
      [  items,   text,   color,   create,   update,   del  ] =
      [ 'items', 'text', 'color', 'create', 'update', 'del' ]
        .map(n => document.getElementById(n));
    
    create.addEventListener('click', () => {
      items.insertAdjacentHTML('beforeend', `<li style="color: ${color.value}">${text.value}</li>`);
      updateForm('', '');
    });
    
    update.addEventListener('click', () => ifActive(a => {
      a.innerText = text.value;
      a.style.color = color.value;
    }));
    
    del.addEventListener('click', () => ifActive(a => a.remove()));
    
    items.addEventListener('click', e => {
      const item = e.target.closest('li');
      if (item) {
        ifActive(a => item !== a && a.classList.remove('active'));
        item.classList.toggle('active');
        ifActive(a => updateForm(a.innerText, a.style.color));
      }
    });
    
    function ifActive(f) {
      const active = items.querySelector('.active');
      active && f(active);
    }
    
    function updateForm(textVal, colorVal) {
      text.value = textVal;
      color.value = colorVal;
    }
    Ответ написан
  • Объединение двух отсортированных массивов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    nums1 = nums1.slice(0, m).concat(nums2).sort((a, b) => a - b);

    Так вы меняете значение ссылки, но не сам массив. Правильно будет так:

    nums1.splice(0, nums1.length, ...[ ...nums1.slice(0, m), ...nums2 ].sort((a, b) => a - b));
    
    // или
    
    nums1.slice(0, m).concat(nums2).sort((a, b) => a - b).forEach((n, i) => nums1[i] = n);

    Но вообще, решение тут другое предполагается, без использования метода sort.
    Ответ написан
    1 комментарий
  • Как округлить число с запятой в большую сторону до десятки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const ceil = (value, precision) => Math.ceil(value / precision) * precision;
    
    
    const values = [ 1, 2, 3, 163, 200.001, 99.999 ];
    values.map(n => ceil(n, 1)); // [ 1, 2, 3, 163, 201, 100 ]
    values.map(n => ceil(n, 10)); // [ 10, 10, 10, 170, 210, 100 ]
    values.map(n => ceil(n, 5)); // [ 5, 5, 5, 165, 205, 100 ]
    Ответ написан
    Комментировать
  • Как из ссылки выбрать цифры в определенном месте?

    0xD34F
    @0xD34F Куратор тега JavaScript
    url.match(/(\d+)\?/)[1]

    или

    /\d+(?=\?)/.exec(url).pop()

    или

    url.split('?', 1).shift().split('/').pop()

    или

    url.replace(/\?.+/, '').replace(/.+\D/, '')
    Ответ написан
    Комментировать
  • Как реализовать на js такую же крутилку, как и в photoshop, выводящую числовое значение от 0 до 360 в input?

    0xD34F
    @0xD34F Куратор тега JavaScript
    HTML
    <div class="angle">
      <div class="angle-input">
        <div class="angle-input-arrow"></div>
      </div>
      <input type="number" min="0" max="360" value="0">
    </div>

    CSS
    .angle {
      display: inline-flex;
      align-items: center;
      border: 1px solid silver;
      padding: 5px;
    }
    
    .angle-input {
      display: inline-flex;
      justify-content: center;
      border: 1px solid black;
      border-radius: 50%;
      width: 50px;
      height: 50px;
      margin-right: 10px;
    }
    
    .angle-input-arrow {
      height: 50%;
      border: 1px solid black;
      transform-origin: 50% 100%;
      box-sizing: border-box;
      pointer-events: none;
    }

    JS
    document.querySelector('.angle input').addEventListener('input', function(e) {
      const arrow = this.closest('.angle').querySelector('.angle-input-arrow');
      arrow.style.transform = `rotate(${e.target.value}deg)`;
    });
    
    const angleInput = document.querySelector('.angle-input');
    
    angleInput.addEventListener('mousedown', onAngleInput);
    angleInput.addEventListener('mousemove', onAngleInput);
    
    function onAngleInput(e) {
      if (e.buttons === 1) {
        const {
          offsetX: x, offsetY: y,
          target: t,
          target: { offsetWidth: w, offsetHeight: h }
        } = e;
    
        const deg = (450 + (Math.atan2(y - h / 2, x - w / 2) * (180 / Math.PI) | 0)) % 360;
        t.querySelector('.angle-input-arrow').style = `transform: rotate(${deg}deg)`;
        t.closest('.angle').querySelector('input').value = deg;
      }
    }

    https://codepen.io/anon/pen/gVRgoX?editors=1010
    Ответ написан
    Комментировать
  • Как разбить массив на два равных?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function chunked(arr, numChunks) {
      const chunks = [];
      const chunkSize = arr.length / numChunks | 0;
      const numLooseItems = arr.length % numChunks;
    
      for (let i = 0, j = 0; j < numChunks; j++) {
        chunks.push(arr.slice(i, i += chunkSize + (j < numLooseItems)));
      }
    
      return chunks;
    }
    
    
    const [ head, tail ] = chunked(arr, 2);
    Ответ написан
    Комментировать
  • Как правильно делать промисы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const wait = time => new Promise(r => setTimeout(r, time));

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

    wait(1000)
      .then(() => { console.log(1); return wait(1000); })
      .then(() => { console.log(2); return wait(1000); })
      .then(() => { console.log(3); });

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

    [ 1, 2, 3 ].reduce((promise, n) => promise
      .then(() => wait(1000))
      .then(() => console.log(n))
    , Promise.resolve());
    
    // или
    
    (async function(...args) {
      for (const n of args) {
        await wait(1000);
        console.log(n);
      }
    })(1, 2, 3);
    Ответ написан
    Комментировать
  • Как установить зависимость элементов?

    0xD34F
    @0xD34F Куратор тега CSS
    const itemSelector = '.parent';
    const className = 'xxx';
    
    document.querySelectorAll(itemSelector).forEach(n => {
      n.addEventListener('mouseenter', onHover);
      n.addEventListener('mouseleave', onHover);
    });
    
    function onHover(e) {
      const state = e.type === 'mouseenter';
      for (
        let el = this;
        (el = el.nextElementSibling) && !el.matches(itemSelector);
        el.classList.toggle(className, state)
      ) ;
    }

    Если только через css - придётся дополнительно стилизовать элементы после следующего .parent, чтобы создать видимость, будто бы стили не применялись:

    .parent:hover ~ .child {
      ...
    }
    
    .parent:hover ~ .parent ~ .child {
      ...
    }
    Ответ написан
    Комментировать