Задать вопрос
  • Что делают эти строки в коде?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Допустим, есть всего 10 слайдов.

    • Производится попытка установить в качестве текущего слайд номер 14. Что делать? Очевидно, установить в качестве текущего четвёртый - остаток от деления изначально указанного номера на количество слайдов.
    • Как установить минус второй (-2) слайд? - очевидно, это второй с конца, надо добавить количество слайдов, чтобы получить реальный номер.
    • Зачем одновременно добавляется количество слайдов и берётся остаток? - чтобы один и тот же код корректно обрабатывал переходы из конца в начало и из начала в конец.
    Ответ написан
    3 комментария
  • Slick slider фильтр и брекпоинты?

    0xD34F
    @0xD34F
    Это какой-то косяк, появившийся в версии 1.9.0 - возьмите предыдущую (на github'е slick'а сейчас в качестве последней обозначена 1.8.1).
    Ответ написан
    1 комментарий
  • Как написать условие генерация точек внутри эллипса?

    0xD34F
    @0xD34F
    Сгенерировали одну координату, через уравнение эллипса нашли ограничения для второй, сгенерировали вторую.

    const WIDTH = 300;
    const HEIGHT = 300;
    const canvas = document.getElementById('canvas');
    canvas.width = WIDTH;
    canvas.height = HEIGHT;
    
    const ctx = canvas.getContext('2d');
    
    const
      X = 100,
      Y = 100,
      A = 90,
      B = 50;
    
    const
      N = 1000,
      SIDE = 4,
      HALF_SIDE = SIDE / 2;
    
    const rand = (min, max) => Math.random() * (max - min) + min;
    
    ctx.beginPath();
    ctx.ellipse(X, Y, B, A, Math.PI / 2, 0, 2 * Math.PI);
    ctx.stroke();
    
    for (let i = 0; i < N; i++) {
      const
        x = rand(-A + HALF_SIDE, A - HALF_SIDE),
        maxAbsY = (B - HALF_SIDE) / A * Math.sqrt(A * A - x * x),
        y = rand(-maxAbsY, maxAbsY);
    
      ctx.beginPath();
      ctx.rect(x + X - HALF_SIDE, y + Y - HALF_SIDE, SIDE, SIDE);
      ctx.stroke();
    }

    https://jsfiddle.net/rLcuy4ko/
    Ответ написан
    1 комментарий
  • Как скопировать действие кнопки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вариант раз - кликнуть кнопку с помощью соответствующего метода:

    button.addEventListener('click', () => {
      anotherButton.click();
    });

    Вариант два - отправить кнопке событие клика (если обработчик клика висит не на самой кнопке, а выше, то надо сделать событие всплывающим):

    button.addEventListener('click', () => {
      anotherButton.dispatchEvent(new Event('click', { bubbles: true }));
    });
    Ответ написан
    Комментировать
  • Где может быть проблема в цикле?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Один и тот же массив помещаете в result. Делайте копию - замените .push(x) на .push([...x]).

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

    function pyramid(n) {
      const result = [];
    
      for (let i = 0; ++i <= n;) {
        const x = [];
        for (let j = 0; ++j <= i; x.push(1)) ;
        result.push(x);
      }
    
      return result;
    }

    А вообще, можно и покороче:

    const pyramid = length => Array.from({ length }, (_, i) => Array(i + 1).fill(1));
    Ответ написан
    Комментировать
  • Как организовать опрос, как на tj?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Структура данных, содержащая вопросы.
    Массив объектов, каждый из которых представляет один вопрос. Внутри два свойства - текст вопроса, и массив с вариантами ответа:

    data: () => ({
      questions: [
        {
          text: '2 x 2?',
          answers: [ '5', '3', '69', '187' ],
        },
        {
          text: '...',
          answers: [ '...', '...', ... ],
        },
        ...
      ],
    }) ,

    Компонент вопроса.
    Принимает три параметра - текст вопроса, массив вариантов ответа, и выбранный ответ:

    props: [ 'text', 'answers', 'value' ],

    Показываем текст вопроса; на основе массива ответов создаём радиокнопки, если ответ совпадает с выбранным, соответствующая кнопка помечается как выбранная; при выборе кнопки отправляем значение родительскому компоненту:

    <div>{{ text }}</div>
    <div v-for="n in answers">
      <label>
        <input
          type="radio"
          :checked="n === value"
          @change="$emit('input', n)"
        >
        {{ n }}
      </label>
    </div>

    Компонент опроса.
    Принимает список вопросов в качестве параметра:

    props: [ 'questions' ],

    Из данных содержит в себе индекс текущего вопроса и массив выбранных ответов:

    data: () => ({
      index: 0,
      answers: [],
    }),

    Если индекс меньше количества вопросов, значит опрос ещё не окончен, показываем вопрос, в противном случае следует отобразить результаты:

    <div v-if="index < questions.length">
      вопрос
    </div>
    <div v-else>
      результаты
    </div>

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

    <question
      v-bind="questions[index]"
      v-model="answers[index]"
    />

    Чтобы перейти к следующему вопросу, достаточно увеличить индекс текущего вопроса (кнопку, пока пользователь не выбрал ответ, можно: а) блокировать - :disabled="!answers[index]"; б) скрывать - v-show="answers[index]"):

    <button @click="index++">дальше</button>

    Результаты - список вопросов и соответствующих им (с тем же индексом) ответов:

    <div v-for="(n, i) in questions">
      {{ n.text }} - {{ answers[i] }}
    </div>


    https://jsfiddle.net/fdbj1w29/
    Ответ написан
    1 комментарий
  • Как получить скобки внутри которой запятая (regex)?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.match(/\((?=[^()]*,)[^()]*\)/)
    Ответ написан
    Комментировать
  • Как отфильтровать объект по массиву значений свойств?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const filterObject = (obj, values) =>
      Object.entries(obj).reduce((acc, [ k, v ]) => (
        values.indexOf(v) !== -1 && (acc[k] = v),
        acc
      ), {});
    
    const result = filterObject(a, b);

    или

    const filterObject = (obj, filter) =>
      Object.fromEntries(Object.entries(obj).filter(n => filter(...n)));
    
    const result = filterObject(a, (k, v) => b.includes(v));
    Ответ написан
    Комментировать
  • Почему не обновляется state после успешного получения данных?

    0xD34F
    @0xD34F Куратор тега Vue.js
    return this.$store.authInfo

    А может, всё-таки this.$store.state.authInfo?
    Ответ написан
    4 комментария
  • Как вставить переменную в регулярное выражение?

    0xD34F
    @0xD34F Куратор тега JavaScript
    RegExp(`^\\d{0,${x}}$`, 'g')
    Ответ написан
    Комментировать
  • Почему неправильно происходит вывод текста из файла?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Всё правильно. Если бы вы составили себе труд ознакомиться с документацией, то знали бы, что

    Объект FileReader позволяет веб-приложениям асинхронно читать содержимое файлов

    Так что console.log выполнять надо внутри обработчика load:

    onFileChange({ target: { files: [ file ] } }) {
      if (file) {
        const reader = new FileReader();
        reader.addEventListener('load', e => {
          this.fileinput = e.target.result;
          console.log(this.fileinput);
        });
        reader.readAsText(file);
      }
    },
    Ответ написан
    Комментировать
  • Функция, которая на входе получает массив объектов вместе с дочерними элементами. Как получить такой массив с многоуровневыми вложениями?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const flat = arr =>
      (arr || []).reduce((acc, { children, ...n }) => {
        if (n.isExpanded || !children) {
          acc.push(n, ...flat(children));
        } else {
          acc.push({ ...n, children });
        }
    
        return acc;
      }, []);

    UPD. Если вложенные уровни надо разворачивать несмотря на isExpanded: false у кого-то из предков уровнем выше родительского, то

    const flat = arr =>
      (arr || []).reduce((acc, { children, ...n }) => {
        const flatChildren = flat(children);
    
        if (n.isExpanded || !children) {
          acc.push(n, ...flatChildren);
        } else {
          acc.push({ ...n, children: flatChildren });
        }
    
        return acc;
      }, []);
    Ответ написан
    1 комментарий
  • Как не присваивать класс, если значение переменной null?

    0xD34F
    @0xD34F Куратор тега Vue.js
    :class="form.FirstName !== null ? form.FirstName ? 'input-successes' : 'input-error' : ''"

    или

    :class="{ 'input-successes': form.FirstName, 'input-error': form.FirstName === false }"

    или

    :class="form.FirstName !== null && [ 'input-error', 'input-successes' ][+form.FirstName]"

    или

    :class="({ true: 'input-successes', false: 'input-error' })[form.FirstName]"

    Лучше бы подобное конечно в computed/метод завернуть, как-то громоздко получается.
    Ответ написан
    2 комментария
  • Как сделать так, чтобы объект не выходил за границы canvas?

    0xD34F
    @0xD34F Куратор тега JavaScript
    this.update = () => {
      const w = this.w / 2;
      const h = this.h / 2;
    
      this.x = Math.max(w, Math.min(W - w, this.x + this.dx));
      this.y = Math.max(h, Math.min(H - h, this.y + this.dy));
    };

    UPD. Вопрос конечно был не об этом, но почему бы не сократить обработчики событий? - а то сейчас просто жуть какая-то.

    document.addEventListener('keydown', e => {
      switch (e.key) {
        case 'ArrowLeft':  pl.dx = -pl.speed; break;
        case 'ArrowRight': pl.dx =  pl.speed; break;
        case 'ArrowUp':    pl.dy = -pl.speed; break;
        case 'ArrowDown':  pl.dy =  pl.speed; break;
      }
    });
    
    document.addEventListener('keyup', e => {
      switch (e.key) {
        case 'ArrowLeft':
        case 'ArrowRight': pl.dx = 0; break;
        case 'ArrowUp':
        case 'ArrowDown':  pl.dy = 0; break;
      }
    });
    Ответ написан
    Комментировать
  • Как к React коду реализующий "лайки" прилепить localStorage.setItem и localStorage.getItem?

    0xD34F
    @0xD34F Куратор тега React
    state = {
      likes: localStorage.getItem('likes') | 0,
    }
    
    plus = () => {
      this.setState(({ likes }) => ({
        likes: likes + 1,
      }), () => localStorage.setItem('likes', this.state.likes));
    }
    Ответ написан
    3 комментария
  • Как не отображать таблицу если в ней нет tr на JQuery или JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const tableId = 'news';
    const trSelector = 'tbody tr';

    Вот jquery:

    $(`#${tableId}`).show().not(`:has(${trSelector})`).hide();
    
    // или
    
    const $table = $('[id="' + tableId + '"]');
    $table.toggle(!!$table.find(trSelector).length);

    А вот jquery нет:

    (t => t.hidden = !t.querySelector(trSelector))
    (document.querySelector('#'.concat(tableId)));
    
    // или (в стили надо будет добавить .hidden { display: none; })
    
    const table = document.getElementById(tableId);
    table.classList.toggle('hidden', Array.prototype.every.call(
      table.tBodies,
      n => !n.rows.length
    ));

    UPD. Наконец-то дождались, теперь js тут не нужен:

    #news:not(:has(tbody tr)) {
      display: none;
    }
    Ответ написан
    6 комментариев
  • Как сделать неактивной кнопку "вперёд" на последнем слайде?

    0xD34F
    @0xD34F
    Выставить infinite: false в настройках слайдера.

    Ну или, если не ищите лёгких путей:

    $slick.on('beforeChange', function(e, slick, currentSlide, nextSlide) {
      $(this).find('.slick-next').prop('disabled', nextSlide === slick.slideCount - 1);
    });

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

    а как ей стиль менять?

    Если отключена бесконечная прокрутка - в крайних положениях кнопкам назначается класс slick-disabled, можете с его помощью переопределять их внешний вид.

    В противном случае - действуете так же, как и в случае с блокировкой кнопки, вместо prop пишите toggleClass, disabled заменяете на имя класса, который отвечает за стилизацию неактивной кнопки.
    Ответ написан
  • Как более грамотно переписать подобный код?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const attacks = [
      { minChance: 7, damage: 40, name: 'critical' },
      { minChance: 5, damage: 20, name: 'big' },
      { minChance: 0, damage: 10, name: 'weak' },
    ];
    
    const messages = {
      start: (player, enemy) => `Welcome! Yor health is - ${player}%, your enemy health - ${enemy}%`,
      end: (player, enemy) => `You ${enemy <= 0 ? 'win' : 'lost'}! Your hp level - ${player}, opponents hp level - ${enemy}`,
      chance: (player, enemy) => `your chance - ${player}, your opponent chance - ${enemy}`,
      turn: (player, enemy, hit, isEnemy) =>
    `${isEnemy ? 'Enemy' : 'Your'} turn...
    ${isEnemy ? 'Enemy' : 'You'} did a ${hit} hit
    ${isEnemy ? 'Your' : 'Enemy'} hp - ${isEnemy ? player : enemy}`,
    };
    
    
    const simpleFight = () => {
      const hp = [ 100, 100 ];
    
      console.log(messages.start(...hp));
    
      while (hp.every(n => n > 0)) {
        const chances = hp.map(() => Math.random() * 11 | 0);
    
        console.log(messages.chance(...chances));
    
        if (chances[0] !== chances[1]) {
          const chance = Math.max(...chances);
          const attack = attacks.find(n => n.minChance < chance);
          const isEnemyAttacks = chance === chances[1];
          hp[+!isEnemyAttacks] -= attack.damage;
    
          console.log(messages.turn(...hp, attack.name, isEnemyAttacks));
        }
      }
    
      console.log(messages.end(...hp));
    };
    Ответ написан
    1 комментарий
  • Как сложить числа между символами?

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

    const sum = str.match(/\d+/g).reduce((acc, n) => acc + +n, 0);
    
    // или
    
    let sum = 0;
    for (const n of str.split(/\D+/)) {
      sum += Number(n);
    }
    
    // или
    
    const sum = eval(str.replace(/\|(\d+)\|/g, '+$1'));

    PHP:

    preg_match_all('/\d+/', $str, $matches);
    $sum = array_sum($matches[0]);
    
    // или
    
    $sum = 0;
    foreach (preg_split('/\D+/', $str) as $n) {
      $sum += intval($n);
    }
    
    // или
    
    eval('$sum = '.preg_replace('/\|(\d+)\|/', '+$1', $str).';');
    Ответ написан
    Комментировать
  • Как из input val передать значение в span?

    0xD34F
    @0xD34F Куратор тега JavaScript
    id="mse2_ms|price_0"

    Да, совсем не говнокод.
    Убить мало дегенерата, который додумался | засунуть в id.

    Указывайте id не через #, а как значение атрибута, т.е. [id="mse2_ms|price_0"].
    Ответ написан