Задать вопрос
  • Как упростить подсчёт нажатий кнопок?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А зачем двигаться "пошагово"? Известны же координаты кнопок - можно вычитать одни из других, и сразу получать количество шагов:

    const keyboard = [
      'abcde123',
      'fghij456',
      'klmno789',
      'pqrst.@0',
      'uvwxyz_/',
    ].reduce((acc, [...row], iRow) => {
      row.forEach((key, iCol) => acc[key] = [ iRow, iCol ]);
      return acc;
    }, {});
    
    function tvRemote(word) {
      let steps = word.length;
      let prev = [ 0, 0 ];
    
      for (const n of word) {
        const curr = keyboard[n];
        steps += Math.abs(prev[0] - curr[0]) + Math.abs(prev[1] - curr[1]);
        prev = curr;
      }
    
      return steps;
    }
    Ответ написан
    2 комментария
  • Vue - валидация объекта в props?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Валидация входных параметров

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

    Решение через фунцию-валидатор я видел, но мне оно не кажется оптимальным для объектов. По крайней мере в React это намного короче и наляднее.

    Возможно во Vue есть аналог?

    Из коробки нет (следует отметить, что в React тоже - начиная с версии 15.5 React.PropTypes является устаревшим, и вместо него следует использовать prop-types). Можете сделать класс и передавать в props конструктор для проверки, что переданный параметр является экземпляром класса. Или используйте сторонние библиотеки, например - там аналог PropTypes.shape есть.
    Ответ написан
  • Почему выдает ошибку "Cannot read property of undefined" при попытке обратиться к свойствам PropTypes?

    0xD34F
    @0xD34F Куратор тега React
    "react": "^16.4.0",

    import React, { Component, PropTypes } from 'react';

    Понятно. Открываем документацию, и видим, что

    Note:
    React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library instead.
    Ответ написан
    2 комментария
  • Как в цикле создавать элементы?

    0xD34F
    @0xD34F Куратор тега React
    Array.from({ length: 5 }, () => <Text>hello, world!!</Text>)
    Ответ написан
    Комментировать
  • Как сделать чтобы модалка работала для всех кнопок?

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

    const modal = document.querySelector('.modal');
    const close = modal.querySelector('.close');
    
    document.addEventListener('click', function(e) {
      if (e.target === modal || e.target === close) {
        modal.style.display = 'none';
      }
    
      if (e.target.tagName === 'BUTTON') {
        modal.style.display = 'block';
      }
    });
    Ответ написан
    1 комментарий
  • Почему шина событий не слышит событие?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Возможная причина номер раз - в тот момент, когда вы делаете emit события, отсутствует экземпляр компонента, где вы пытаетесь его слушать.

    Возможная причина номер два:

    bus.$off('selectedCompanies')

    Толково придумано. Давайте представим, что создаётся два... нет, лучше пять экземпляров компонента. Затем один удаляется. Вопрос - сколько после этого останется обработчиков события selectedCompanies? Думаете, что четыре? А вот и нет - ни одного. Надо всё-таки указывать, какой именно обработчик вы удаляете.

    Наконец, возможная причина номер три:

    Есть 2 независимы страницы.

    Очень надеюсь, вы подразумеваете не разные вкладки/окна браузера.
    Если всё-таки да...

    ...ну, поздравляю - чего-то вы в этой жизни не понимаете, от слова совсем. Нет реакции на событие потому, что шин у вас две - и ничего они друг о друге не знают. В этом случае вам нужна не шина, а надо как-то пересылать информацию между вкладками. Для этого можно использовать localStorage (есть плагины для vuex под это дело, можете погуглить), или BroadcastChannel.
    Ответ написан
  • Почему при поиске вылезает TypeError: Cannot read property 'toString' of null?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Какое-то из свойств объекта оказалось null'ом. Почему бы не добавить проверку перед toString'ом - что именно вы собираетесь преобразовывать? Может и не надо перегонять null'ы в строки, может, в этом случае результат поиска сразу отрицательный должен быть. Ну или преобразовывайте в строку как-нибудь иначе, варианты разные есть: ('' + m) или `${m}` или String(m).

    А вообще, вы конечно поторопились вот так в лоб использовать первый попавшийся код. Вон, у вас там ещё и вложенные объекты есть, по их свойствам поиск корректно работать не будет (т.к. дефолтное строковое представление объекта - это '[object Object]') - об этом вы подумали? Нет, точно надо проверять, что за значение:

    return this.sortedTokens_VMP.filter(n => Object.values(n).some(m => {
      if (m instanceof Object) {
        // проверяем объект, возможно, стоит сделать какую-нибудь рекурсивную функцию под это дело
      } else if (typeof m === 'number') {
        // а вдруг числа надо обрабатывать иначе, чем строки
      } else {
        // какая-то дефолтная проверка значения
      }
    }));

    UPD. А сортировка, сортировка-то - тоже ведь ерунда получится при работе с null'ами и вложенными свойствами.

    Вот как всё будет:

    Рекурсивная функция, которая проверяет, есть ли где во вложенных объектах указанная строка:

    const includes = (obj, str) => Object
      .values(obj)
      .some(n => n instanceof Object
        ? includes(n, str)
        : `${n}`.toLowerCase().includes(str)
      );

    Используем её внутри вычисляемого свойства, представляющего отфильтрованные данные:

    filteredTokens_VMP() {
      const s = this.search.toLowerCase();
      return this.sortedTokens_VMP.filter(n => includes(n, s));
    },

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

    const getNested = (root, path) => path
      .split('.')
      .reduce((p, c) => p != null ? p[c] : p, root);

    Используем её в вычисляемом свойстве, представляющем отсортированные данные, если попадается nullish значение, будем загонять соответствующий элемент в конец:

    sortedTokens_VMP() {
      const reverse = this.sort.reverse ? -1 : 1;
      return this.tokens_VMP
        .map(n => [ getNested(n, this.sort.key), n ])
        .sort(([a], [b]) => reverse * (
          a == null ?  Infinity :
          b == null ? -Infinity :
          a < b     ?        -1 :
          a > b     ?         1 :
                              0
        ))
        .map(n => n[1]);
    },
    Ответ написан
  • Как организовать поиск во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    вот пример - https://codepen.io/pespantelis/pen/ojwgPB?editors=1010,
    но здесь используется версия vue/0.12.16/vue.min.js

    Нет проблем переписать с использованием актуальной версии vue.
    Ответ написан
    1 комментарий
  • Почему некорректно работает условие проверки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Что если пользователь введёт значение, которое нельзя привести к числу? Получите NaN, этот случай у вас никак не обрабатывается.

    Результат повторного ввода в переменную count не записывается, если первый раз ввели некорректное значение, то оно там так и останется.

    Кроме того, непонятно, почему вы решили, что пользователю хватит всего двух попыток, чтобы ввести корректные данные. Это абсурд. Сделайте цикл, пусть мучается до победного конца:

    let count = null;
    while (1) {
      count = prompt('Введите количество колонок для таблицы умножения') | 0;
      if (count > 0) {
        break;
      }
      alert('Введите корректное число');
    }
    Ответ написан
    Комментировать
  • Почему вылезает ошибка "Uncaught TypeError: Cannot read property '0' of undefined"?

    0xD34F
    @0xD34F Куратор тега JavaScript
    lat + x != 11

    lon + y != 11

    А 10, стало быть, является допустимым значением, да? И это значение вы используете в качестве индекса массива, чей размер - тоже 10. Толково придумано, ничего не скажешь.
    Ответ написан
    1 комментарий
  • Почему возникает ошибка "unknown action type"?

    0xD34F
    @0xD34F
    Потому что нет экшена. Что непонятного-то? Раз нет, а вызывать надо - добавьте его.

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

    я понял, что нет экшена. Вопрос в том, что он есть )

    Не говорите ерунды, ошибка вываливается - значит нет. То, что вы показали метод с таким-то именем, ещё не значит, что у вас есть такой экшен.

    Какие могут быть варианты:
    • Вместо actions засунули его в mutations
    • Допустили опечатку - вместо actions написали anctions или action или actons или...
    • Забыли подключить модуль, в котором экшен находится
    • Неправильно вызываете - экшен находится в namespaced модуле
    • ...

    Проверяйте код своего хранилища, думайте.
    Ответ написан
  • Как можно упростить декодирование кода морзе?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const decodeMorse = code => code
      .trim()
      .split('   ')
      .map(n => n.split(' ').map(m => MORSE_CODE[m]).join(''))
      .join(' ');

    или

    const decodeMorse = code => code
      .trim()
      .replace(/\S+ ?/g, m => MORSE_CODE[m.trim()])
      .replace(/  /g, ' ');
    Ответ написан
    Комментировать
  • Как сделать микшер цветов на vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Создадим объект, который будет содержать компоненты цвета:

    colorComponents: {
      r: 0,
      g: 0,
      b: 0,
    },

    На основе этого объекта создадим элементы управления значениями компонентов цвета:

    <div v-for="(v, k) in colorComponents">
      {{ k }}
      <input v-model="colorComponents[k]" type="range" min="0" max="255">
      {{ v }}
    </div>

    И стилизуем какой-нибудь элемент, вычисляя итоговый цвет:

    <div :style="style">

    computed: {
      style() {
        return {
          'background-color': `rgb(${Object.values(this.colorComponents).join(',')})`,
        };
      },
    },

    jsfiddle.net/o1xe8gmk/1
    Ответ написан
    Комментировать
  • Как лучше реализовать выбор не более скольких-то элементов из списка по клику?

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

    const itemSelector = '.item';
    const activeClass = 'active';
    const maxActive = 3;
    const onMaxActiveClick = () => alert(`больше ${maxActive} нельзя`);
    
    
    // делегирование, назначаем обработчик клика один раз для всех элементов
    document.addEventListener('click', function(e) {
      const item = e.target.closest(itemSelector);
      if (item) {
        const active = document.querySelectorAll(`${itemSelector}.${activeClass}`);
        if (active.length < maxActive || item.classList.contains(activeClass)) {
          item.classList.toggle(activeClass);
        } else {
          onMaxActiveClick();
        }
      }
    });
    
    // или, назначаем обработчик клика каждому элементу индивидуально
    let activeCount = 0;
    
    for (const n of document.querySelectorAll(itemSelector)) {
      n.addEventListener('click', onClick);
      activeCount += n.classList.contains(activeClass);
    }
    
    function onClick({ currentTarget: item }) {
      if (activeCount < maxActive || item.classList.contains(activeClass)) {
        activeCount += item.classList.toggle(activeClass) ? 1 : -1;
      } else {
        onMaxActiveClick();
      }
    }
    Ответ написан
    Комментировать
  • Почему иногда выходит ошибка " Uncaught TypeError: Cannot read property '3' of undefined "?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кажется, кто-то не в курсе, что индексация массивов начинается с нуля.

    Ну нет у вас ни в одном из массивов элемента с индексом 10, нет. Соответственно, когда lon принимает значение 10, map[lon] оказывается undefined, отсюда и ошибка.
    Ответ написан
    1 комментарий
  • Почему не работает ngModel?

    0xD34F
    @0xD34F
    А не многовато ли у вашего ngModel скобок?
    Ответ написан
    Комментировать
  • Можли ли продолжить всплытие собственных событий в vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    А можно ли как то прокинуть это событие далее(всплытие), что бы можно было его прослушать на любом компоненте-предке, в том числе и на корневом?

    Вручную в каждом компоненте делайте emit, или гуглите, как сделать шину событий (event bus) - можно будет подписываться на нужное событие где угодно.
    Ответ написан
    1 комментарий
  • Не работает radio checked?

    0xD34F
    @0xD34F Куратор тега CSS
    В чем ошибка?

    В том, что вы почему-то решили не разбираться, как именно работает используемый вами инструмент.

    Поменяйте input и span местами - будет работать как вам нужно.
    Ответ написан
    Комментировать
  • Как обновлять ссылку на элемент после использования drag&drop?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Делегируйте обработку событий, и тогда не придётся беспокоиться о пропавших обработчиках. Как-то так.
    Ответ написан
    7 комментариев