Задать вопрос
  • Как сложить две элемента в массиве и выдать результат?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Посчитать суммы соседних элементов можно так:

    const sums = arr.reduce((acc, n, i) => (
      (i & 1) || acc.push(0),
      acc[acc.length - 1] += n,
      acc
    ), []);
    
    // или
    
    const sums = arr.reduce(
      (acc, n, i) => (acc[i / 2 | 0] += n, acc),
      Array(Math.ceil(arr.length / 2)).fill(0)
    );
    
    // или
    
    const sums = Array.from(
      { length: arr.length / 2 + arr.length % 2 },
      (n, i) => arr[i * 2] + (arr[i * 2 + 1] || 0)
    );
    
    // или
    
    const sums = eval(`[${arr}]`.replace(/(\d+),(\d+)/g, '$1+$2'));

    А собрать из массива строку так:

    const result = sums.join(' ');
    
    // или
    
    const result = sums.reduce((acc, n) => acc + (acc && ' ') + n, '');
    
    // или
    
    const result = ''.concat(...sums.flatMap((n, i) => i ? [ ' ', n ] : n));
    
    // или
    
    const result = String(sums).replace(/,/g, ' ');
    Ответ написан
    1 комментарий
  • Как скрыть опасную функцию?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const { function1, function2 } = (function() {
      function unsafe() {}
    
      return {
        function1() {},
        function2() {},
      };
    })();
    Ответ написан
    Комментировать
  • Как выполнить условную отрисовку внутри template компонента VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Можно ли получать высшее образование, не имея среднего? Очевидно, нет. А осваивать фронтенд-фреймворк, не имея базовых знаний html/js? Судя по показанному коду, вы не в курсе, что атрибуты id должны иметь уникальные значения (<span id="wrong"> в шаблоне компонента - а если экземпляров компонента будет несколько?), путаетесь с операторами - использовали побитовое ИЛИ там, где должно было быть логическое. Может, стоит подождать с vue и подтянуть основы?

    А если отвечать непосредственно на ваш вопрос... Ну, держите.
    Ответ написан
    Комментировать
  • Как во vue js отследить момент когда все дочерние компоненты подгрузили данные?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Наверное, ваш дочерний компонент знает своё состояние - производится ли загрузка данных или нет. А значит, может сигнализировать об изменении своего состояния родителю - с помощью событий. А в родителе можно на эти события подписаться. Например (вместо ajax запросов тут генерация случайных чисел по таймауту, но думаю суть ясна).
    Ответ написан
  • Cоздать компонент Vue и событие внутри него?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вариант раз, размер шрифта делаем свойством компонента, ну и v-model + watch:

    data: () => ({
      size: ...
    }),
    watch: {
      size: {
        immediate: true,
        handler(val) {
          fontSize(this.target, val);
        },
      },
    },

    <input type="range" v-model="size">

    Вариант два - слушаем событие input:

    methods: {
      onInput(e) {
        fontSize(this.target, e.target.value);
      },
    },
    mounted() {
      this.$el.querySelector('input').dispatchEvent(new Event('input'));
    },

    <input type="range" @input="onInput">
    Ответ написан
    Комментировать
  • Какая должна быть регулярка для проверки чисел в строке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const isPositiveInteger = RegExp.prototype.test.bind(/^\d+$/);
    
    // или
    
    const isPositiveInteger = str =>
      !(!str || str.replace(/\d/g, ''));
    
    // или
    
    const isPositiveInteger = str =>
      Boolean(str) && !str.match(/\D/);

    Нужна именно регулярка, т.к. числа большой длины.

    Нет, не "т.к.". Т.к. строку можно проверить и без регулярных выражений:

    const isPositiveInteger = str =>
      str !== '' && [...str].every(n => Number.isInteger(+n));
    
    // или
    
    function isPositiveInteger(str) {
      for (const n of str) {
        if (!'0123456789'.includes(n)) {
          return false;
        }
      }
    
      return str.length > 0;
    }
    
    // или
    
    function isPositiveInteger(str) {
      let result = !!str;
    
      for (let i = 0; i < str.length && result; i++) {
        const n = str.charCodeAt(i);
        result = 47 < n && n < 58;
      }
    
      return result;
    }
    Ответ написан
    1 комментарий
  • Как менять класс родителя при выборе радиокнопки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const containerSelector = '.form-fields';
    const itemSelector = `${containerSelector} .wrapper-from-field`;
    const activeClass = 'active';
    const toggle = item => item
      .closest(containerSelector)
      .querySelectorAll(itemSelector)
      .forEach(n => n.classList.toggle(activeClass, n === item));

    document.querySelectorAll(itemSelector).forEach(function(n) {
      n.addEventListener('change', this);
    }, e => toggle(e.currentTarget));
    
    // или
    
    document.addEventListener('change', e => {
      const item = e.target.closest(itemSelector);
      if (item) {
        toggle(item);
      }
    });
    Ответ написан
  • Как конвертировать дату в unix?

    0xD34F
    @0xD34F Куратор тега JavaScript
    берёте moment.js и: moment(dateStr, 'MMM D, YYYY at hh:mm A').unix()

    или, если подрезать строку, можно будет обойтись без сторонних библиотек:

    Date.parse(dateStr.replace('at', '')) / 1000
    Ответ написан
    Комментировать
  • Как сделать код короче?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getCard = button => $(`#card${button.id.match(/\d+/).pop()}`);
    
    $('[id^="button"]').hover(
      e => getCard(e.target).fadeIn(),
      e => getCard(e.target).fadeOut(),
    );

    или

    const $buttons = $('[id^=button]').hover(function(e) {
      this.eq($buttons.index(e.target))[e.type === 'mouseenter' ? 'fadeIn' : 'fadeOut']();
    }.bind($('[id^=card]')));
    Ответ написан
    Комментировать
  • Как при добавлении новой строки, к элементу крепить виджет datepicker?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Правильный вариант: отказаться от использования jquery, и взять какой-нибудь готовый компонент для vue. Можете заглянуть на awesome-vue, там есть список, может присмотрите себе что-нибудь.

    Ну а так-то всё тривиально: вешаете ref на элементы, которые должны быть дейтпикерами; вешаете наблюдателя на массив с данными, в котором обходите элементы и инициализируете виджет там, где его нет:

    <input ref="datepicker" v-model="item.date">

    watch: {
      items() {
        this.$nextTick(() => {
          this.$refs.datepicker
            .filter(n => !n.classList.contains('hasDatepicker'))
            .forEach(n => $(n).datepicker({
              onSelect: () => n.dispatchEvent(new Event('input')),
            }));
        });
      },
    },

    Или можно директиву сделать:

    <input v-datepicker v-model="item.date">

    Vue.directive('datepicker', {
      inserted: el => $(el).datepicker({
        onSelect: () => el.dispatchEvent(new Event('input')),
      }),
    });

    Или даже целый компонент:

    <v-datepicker v-model="item.date"></v-datepicker>

    Vue.component('v-datepicker', {
      template: `<input :value="value" readonly="readonly">`,
      props: [ 'value' ],
      mounted() {
        $(this.$el).datepicker({
          onSelect: date => this.$emit('input', date),
        });
      },
    });


    Кстати, вам ещё в шаблоне надо будет добавить key в список пользователей.
    Ответ написан
  • Как передать значение из data в атрибут html во vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Используйте динамическую привязку значения.

    Само значение собирайте с использованием обычных javascript-выражений:

    :src="`/img/${imgName}.jpg`"

    или

    :src="'/img/' + imgName + '.jpg'"

    Также можно сделать вычисляемое свойство, если imgName является свойством компонента:

    computed: {
      imgSrc() {
        return `/img/${this.imgName}.jpg`;
      },
    },

    :src="imgSrc"

    Или сделайте метод, если собирать путь к изображению требуется более чем в одном месте, с разными name'ами:

    methods: {
      imgSrc: name => `/img/${name}.jpg`,
    },

    :src="imgSrc(imgName)"
    Ответ написан
    Комментировать
  • Как сделать фильтрацию по нескольким параметрам?

    0xD34F
    @0xD34F Куратор тега React
    Положить в стейт фильтры - массив объектов, содержащих имя свойства, по которому выполняется фильтрация, текущее значение, массив значений, доступных для выбора:

    filters: [
      { field: 'bg', value: '', options: [ 'black', 'white' ] },
      { field: 'color', value: '', options: [ 'red', 'green' ] },
    ],

    На основе этого массива создать элементы фильтров:

    filters.map((n, i) => (
      <label>
        {n.field}:
        <select data-index={i} onChange={this.onChange}>
          <option value="">none</option>
          {n.options.map(n => <option>{n}</option>)}
        </select>
      </label>
    ))

    onChange = e => {
      const index = +e.target.dataset.index;
      const value = e.target.value;
    
      this.setState(prevState => ({
        filters: prevState.filters.map((n, i) => index === i ? { ...n, value } : n)
      }));
    }

    Получить отфильтрованные данные:

    const filteredData = filters.reduce((acc, n) => {
      return n.value
        ? acc.filter(m => m[n.field].includes(n.value))
        : acc;
    }, data);

    Вместо полных данных отобразить отфильтрованные.
    Ответ написан
    1 комментарий
  • Почему не работает кнопка?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что у вас имя переменной - top, и она глобальная. Но глобальной переменной с таким именем быть не может, место уже занято. Так что когда вы делаете top += 2, вы вовсе не с числом работаете. Меняйте имя переменной или выполняйте свой код в области видимости, отличной от глобальной или сделайте свой top свойством какого-нибудь объекта или...
    Ответ написан
  • Исполнение JS, полученного с сервера в компоненте VUE. Можно ли?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Можно. Только это называется не "исполнение js", а компиляция шаблона. Смотрите Vue.compile.
    Ответ написан
  • Как реализовать фильтр в react-table?

    0xD34F
    @0xD34F Куратор тега React
    Сделайте кастомный фильтр, с обработчиками onChange и onKeyPress, в которых и будет происходить переключение функции фильтрации. Например, так (поле lastName, посмотреть в деле можно вбивая короткие слова, которые являются частью более длинных - такие как war, son, comb, sign, child, work, can и т.п.).

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

    у меня много столбцов, плюс к этому много таблиц, и логику фильтра нужно применить ко всему

    Ну так сделайте компонент-обёртку для этой таблицы, который будет задавать дефолтный компонент фильтра и дефолтную же функцию фильтрации - их вы можете взять из моего примера.

    UPD. https://codesandbox.io/s/nn1z53jn4l (только первые три поля, у последнего фильтр оставлен переопределённым).
    Ответ написан
    5 комментариев
  • Как сделать, чтобы отображаемый select'ом текст отличался от текста выбранного option'а?

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

    select.innerHTML = [
      { val:  69, optionText:  'hello, world!!', selectText:  'HELLO, WORLD!!' },
      { val: 187, optionText:  'fuck the world', selectText:  'FUCK THE WORLD' },
      { val: 666, optionText: 'fuck everything', selectText: 'FUCK EVERYTHING' },
    ].map(n => `
      <option value="${n.val}" hidden>${n.selectText}</option>
      <option value="${n.val}">${n.optionText}</option>
    `).join('');
    
    select.addEventListener('change', e => e.target.value = e.target.value);
    Ответ написан
  • Как вывести элементы htmlcollection в цикле на странице?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Откуда и куда копируем:

    const source = document.querySelector('.menu');
    const target = document.querySelector('#parent');

    • Вариант раз - cloneNode.

      Можно перебирать элементы и копировать их по одному:

      for (const n of source.children) {
        target.appendChild(n.cloneNode(true));
      }
      
      // или
      
      source.querySelectorAll(':scope > *').forEach(n => {
        target.insertAdjacentElement('beforeend', n.cloneNode(true));
      });

      А можно скопировать их родителя:

      // вложенные узлы копии добавляем в целевой элемент
      target.append(...source.cloneNode(true).children);
      
      // или, заменяем целевой элемент копией исходного
      target.replaceWith(source.cloneNode(true));

    • Вариант два - копируем не сами элементы, а разметку:

      target.innerHTML = source.innerHTML;
      
      // или
      
      target.outerHTML = source.outerHTML;

    Ответ написан
    Комментировать
  • Как выводить день недели и месяц зная порядковый номер дня года?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function getDate(day, year = new Date().getFullYear()) {
      const date = new Date(year, 0, day);
      return [
        date.getDate(),
        [
          'январь', 'февраль', 'март', 'апрель', 'май', 'июнь',
          'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'
        ][date.getMonth()],
        [ 'вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб' ][date.getDay()],
      ].join(' ');
    }
    
    
    getDate(115, 2019) // "25 апрель чт"

    или

    const getDate = (day, year = new Date().getFullYear()) =>
      new Date(year, 0, day).toLocaleString('ru-RU', {
        day: 'numeric',
        month: 'long',
        weekday: 'short',
      });
    
    
    getDate(115, 2019) // "чт, 25 апреля"
    Ответ написан
  • Почему не срабатывает скрипт jquery?

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

    $('.close-panel').on('click', function(e) {
      e.stopPropagation();
      $('.add-caption').removeClass('active');
    });

    Или, уберите отдельный обработчик клика по .close-panel, а в обработчике клика по .add добавляйте или убирайте класс в зависимости от того, откуда пришло событие:

    $('.add').on('click', function(e) {
      $('.add-caption').toggleClass('active', !$(e.target).hasClass('close-panel'));
    });
    Ответ написан