Задать вопрос
  • Как реализовать генератор чисел?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getRandomInt = (min, max) => (Math.random() * (max - min + 1) + min) | 0;
    setInterval($counter => $counter.text(getRandomInt(200, 300)), 500, $('.counter'));
    Ответ написан
    Комментировать
  • Как вырезать из url имя файла?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.match(/([^/]+)\.[^\.]+$/)[1]
    
    // или
    
    str.split('/').pop().split('.').shift()
    
    // или
    
    str.split(/[/.]/).slice(-2)[0]
    
    // или
    
    str.replace(/.*\//, '').replace(/\..*/, '')
    
    // или
    
    str.slice(str.lastIndexOf('/') + 1, str.lastIndexOf('.'))
    Ответ написан
    Комментировать
  • CSS. Как выставить ширину li в зависимости от контента?

    0xD34F
    @0xD34F Куратор тега CSS
    Никакую ширину под контент подстраивать не надо. Расположите элементы в обратном порядке - тогда заработает селектор .myLink:hover ~ .marker, а чтобы они отображались по-старому, можно использовать flex. Как-то так.
    Ответ написан
    2 комментария
  • Как создать массив с рандомными повторяющимися числами?

    0xD34F
    @0xD34F Куратор тега JavaScript
    чтобы числа повторялись не более двух раз

    Ну, очевидно же - создать два массива со случайными числами и объединить их. Как создать массив со случайными не повторяющимися числами - недавно рассказывал.
    Ответ написан
    5 комментариев
  • Как изменить маркер по клику на него в яндекс картах?

    0xD34F
    @0xD34F Куратор тега Яндекс.Карты
    Вешаете обработчик клика, внутри делаете options.set. Например.
    Ответ написан
  • Как отсортировать цену с учетом скидки по возрастанию?

    0xD34F
    @0xD34F
    SELECT *, price * ((100 - discount) / 100) AS discounted
    FROM prices
    ORDER BY discounted
    LIMIT 10
    Ответ написан
    5 комментариев
  • Как сделать добавление/удаление активному input Jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $(document).on({
      focus() {
        $(this).addClass('active-amount-input');
      },
      blur() {
        $(this).removeClass('active-amount-input');
      },
    }, '.amount, .amount_1');

    или

    $(document).on('focusin focusout', '.amount, .amount_1', e => {
      $(e.currentTarget).toggleClass('active-amount-input', e.type === 'focusin');
    });
    Ответ написан
    2 комментария
  • Как div с изображением оставить по центру при движении sidebar?

    0xD34F
    @0xD34F Куратор тега CSS
    Смещайте сайдбар, а не main (ну и кнопку открытия-закрытия тоже - поскольку она вне сайдбара).

    Изменяем назначение классов:

    - <main className={active ? 'move-to-left' : ''}>
    + <main>

    - <div className="sidebar">
    + <div className={'sidebar ' + (active ? 'move-to-left' : '')}>

    - <NavRight onClick={this.toggleActive} buttonClass={!active ? 'active' : ''} navClass="hidden-xs" />
    + <NavRight onClick={this.toggleActive} buttonClass={active ? 'active move-to-left' : ''} navClass="hidden-xs" />

    И стили:

    + body {
    +   overflow: hidden;
    + }

    .sidebar {
      ...
    - z-index: 1;
    - right: 0;
    + z-index: 3;
    + right: -400px;
    + transition: all .7s ease;

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

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

    Вместо того, чтобы делать transform, меняйте ширину. Как-то так.
    Ответ написан
    3 комментария
  • Почему при постфиксном инкременте стейт не изменяется?

    0xD34F
    @0xD34F Куратор тега React
    Вам бы разобраться, как оператор ++ работает. Сначала вы изменяете значение state.counter напрямую (чего делать НЕ НАДО), затем setState устанавливает в качестве нового значения counter'а его предыдущее значение, возвращаемое постфиксным ++.
    Ответ написан
  • Как получить разницу между датами в typescript в миллисекундах для обратного отчета времени?

    0xD34F
    @0xD34F
    TS2362 The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum

    Ну да. Надо преобразовывть даты в числа при вычитании, т.е., вместо

    this.endDate - this.currentDate

    пусть будет

    +this.endDate - +this.currentDate

    , например. Ну а в целом, то что вы делаете - это просто бред сумасшедшего. Зачем вам пять разных интервалов? Что вы пытаетесь сделать в коллбеках этих интервалов? - результаты ваших вычислений улетают в никуда. Говорите, ваша цель - обратный отсчёт? Давайте я вам покажу, как он может выглядеть, а вы посмотрите, и подумаете, что к чему.
    Ответ написан
    Комментировать
  • Исключить повторяющиеся объекты?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const uniqueDocs = docs
      .filter((n, i, a) => n === a.find(m => m.date === n.date && m.type === n.type))
      .map(({ type, date }) => ({ type, date }));

    или

    const uniqueDocs = Object
      .entries(docs.reduce((acc, n) => ((acc[n.type] = acc[n.type] || new Set).add(n.date), acc), {}))
      .reduce((acc, n) => (acc.push(...Array.from(n[1], m => ({ type: n[0], date: m }))), acc), []);

    или

    const unique = (arr, keys) =>
      arr.filter((n, i, a) => i === a.findIndex(m => keys.every(k => n[k] === m[k])));
    
    const pick = (obj, keys) =>
      keys.reduce((acc, k) => (acc[k] = obj[k], acc), {});
    
    
    const keys = [ 'type', 'date' ];
    const uniqueDocs = unique(docs, keys).map(n => pick(n, keys));
    Ответ написан
  • Как динамически выводить элементы массива?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделаем объект, который следует выводить, вычисляемым свойством:

    obj() {
      return this.items[0];
    },

    Если он существует - выводим:

    <div v-if="obj">
      <div v-for="(val, key) in obj">
        ...

    Похоже на то, что вам надо?
    Ответ написан
    1 комментарий
  • Как кастомизировать тултип в ngx-charts?

    0xD34F
    @0xD34F
    Если я правильно понял что вам нужно, то вместо seriesTooltipTemplate надо было передавать tooltipTemplate, типа так.
    Ответ написан
    Комментировать
  • Выборка внутри блока на jQuery скрипта по добавлению класса?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Проверяйте, где был клик:

    $('.shop-ellement-sidebar').on('click', function(e) {
      if ($(e.target).closest('.element-sidebar_content').length) {
        return;
      }
      // дальше проверка наличия класса active и т.д. - без изменений

    Или останавливайте всплытие события при клике на .element-sidebar_content:

    $('.element-sidebar_content').click(function(e) {
      e.stopPropagation();
    });
    Ответ написан
    3 комментария
  • Динамичская загрузка и рендеринг компонента?

    0xD34F
    @0xD34F Куратор тега Vue.js
    new Vue({
      router,
      store,
      components: {
        AppModile: () => import('@/AppMobile.vue'),
        App: () => import('@/App.vue')
      },
      render: h => h(isMobile ? 'AppMobile' : 'App')
    }).$mount('#app')
    Ответ написан
    Комментировать
  • Vuex для каталога с корзиной - как лучше реализовать такое решение?

    0xD34F
    @0xD34F Куратор тега Vue.js
    получать данные для корзины - в actions, через Promise.all по id вытаскивая данные для каждого товара?

    В смысле - хранить в cartItems только id (ну ещё количество и цену), а при каждом заходе пользователя в корзину подтягивать остальные данные (название/производитель/гарантия/...)? Во-первых, что ещё за Promise.all - собираетесь ради каждого товара выполнять отдельный запрос? Так дела не делаются - передавать на сервер следует массив id, запрос должен быть один. Во-вторых - получится, что у вас есть в хранилище массив id, а в компоненте корзины локально лежат полные данные товаров. На мой взгляд - как-то сложновато, при манипуляции данными cartItems из компонента корзины последний придётся вручную поддерживать в актуальном состоянии - watch на cartItems, отфильтровывание из локального массива удалённых элементов, копирование количества существующих.

    Короче, я при добавлении товара в корзину просто полностью бы копировал в cartItems данные из products.
    Ответ написан
    2 комментария
  • Как еще можно оптимизировать js код?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Исправил синтаксические ошибки.

    Ага, на пять с плюсом.

    • Пропущен if или условие лишнее:

      } else (date.getDay() == 0) {

      } else (a < 1) {

    • Лишнее : после ?:

      this.updateTime.getMonth() > 9 ? : '0'

    • Перед методом renderItems стоит лишняя фигурная скобка, а после метода createPeriod такой скобки не хватает.


    И это только синтаксические. Есть ещё ворох иных.

    • Имена свойств, содержащих обработчики событий, состоят из букв только в нижнем регистре, тут должно было быть input.onchange:

      this.input.onChange = this.onChange;

    • Какое там первое слово в имени базового класса должно быть - date или data? Вы бы определились:

      class dateInput {

      class dateRange extends dataInput {

    • В конструкторе dateRange отсутствует вызов конструктора базового класса - не хватает super(); перед this.container = ...:

      constructor() {
       this.container = document.querySelector('.containerForLastUpdateRecordAndPeriodItems');

    • Это ещё что за на хрен:

      period = `${date.toLocaleDateString()} - {date.setHours(168).toLocaleDateString()}`;

      Во-первых - не указан индекс, и вместо собираемого массива используется объект, переданный в функцию, вместо period должно быть periods[i].
      Во-вторых- метод setHours возвращает число, а не объект даты, так вызвать toLocaleDateString не получится.
      В-третьих - отсутствует $ перед фигурной скобкой при подстановке второй даты.

    • Присваивание значений необъявленным переменным:

      b = false;

      element = document.createElement('div')

      Никогда так больше не делайте. Ну и бегом гуглить, почему это плохо.

    • Неправильно пытаетесь вызывать метод renderItems - не хватает this.:

      onChange() {
       renderItems(this.createItems(this.createPeriod(this.inputValue)));

      Кроме того, this тут будет вовсе не экземпляром класса - надо привязывать контекст при установке этого метода в качестве обработчика события (this.onChange.bind(this) - это в конструкторе dateInput). А ещё, поскольку метод переопределён, надо не забыть вызвать метод базового класса, иначе не будет установлено значение свойства inputValue:

      onChange(e) {
        super.onChange(e);
        this.renderItems(...

    • Можете хоть из кожи вон вылезти, но константа своего значения не изменит, а вот TypeError при попытке выполнить хотя бы одну итерацию подобного цикла получите обязательно:

      for (const i = 0; i < n-a; i++) {

    • Что принимает document.createElement в качестве параметров? Откройте документацию и разберитесь, чтобы такую чушь больше не сочинять:

      const element = document.createElement('div', {textContent: item});

    • Опять проблемы со значением this:

      this.container.appendChild(element);

      Поскольку данная строка находится внутри коллбека forEach, который представлен обычной функцией, то экземпляр класса оказывается недоступен. Или замените обычную функцию на стрелочную, или передайте this в forEach третьим параметром.

    • Это ещё что за на хрен №2:

      createPeriod(date) {
       var newDate = date;
        newDate.year = newDate.year + 1;

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

      createPeriod(dateStr) {
        const start = new Date(dateStr);
        const end = new Date(dateStr);
        end.setFullYear(end.getFullYear() + 1);
        return { start, end };
      }

    • Это ещё что за на хрен №3:

      const range = Object.create(dateRange.prototype); 
      range.constructor = range.constructor.bind(range); 
      range.constructor();

      Во-первых, без new конструктор вызывать нельзя.
      Во-вторых - к чему такие сложности? - достаточно new dateRange;.


    А уж что касается общей логики данного кода и насколько он соответствует поставленной задаче (о которой вы почему-то решили умолчать, так что здесь можно было бы говорить только в предположительном ключе), то я даже пытаться думать в эту сторону не буду. Хотя несомненно, что и тут всё очень-очень плохо - раз уж вы при написании кода накосячили как только можно и как нельзя, то почему на этапе проектирования должно было быть что-то принципиально иное?

    Подскажите, как еще можно оптимизировать(зарефакторить) данный js код?

    А зачем? Лучшее, что тут можно сделать - выбросить всё на хрен и попробовать написать заново, предварительно подумав, на этот раз головой вместо задницы. Не стыдно подобный мусор показывать?

    Но окей, окей - метод createItems, например:

    • Странные непонятные числа, встречающиеся в коде - такого не надо, определяем константы, имена которых будут указывать, что это за значения:

      const MS_IN_HOUR = 3600000;
      const HOURS = 168;

    • Вместо двух циклов сделайте один - промежуточный массив dates не нужен:

      for (let i = +period.start; i < +period.end; i += MS_IN_HOUR * HOURS) {
        const date = new Date(i);

    • "Оптимизируйте" if-else-if-... - складываем нижние значения часов в массив (тоже бы неплохо определить его отдельно, дав осмысленное имя), извлекаем их используя день недели как индекс, верхнее значение получаем добавляя сколько там надо (я так понял, разница везде одинаковая между нижним и верхним):

      const hours = [ -120, 0, -24, -48, -48, -72, -96 ][date.getDay()];
      periods.push([ hours, hours + HOURS ]
        .map(n => (date.setHours(n), date.toLocaleDateString()))
        .join(' - ')
      );

    • Для обмена значениями дополнительная переменная не нужна:

      [ periods[i + a], periods[i] ] = [ periods[i], periods[i + a] ];



    Или, renderItems:

    Четыре обращения к свойству updateTime - как-то многовато, достаточно одного, чтобы запомнить значение под коротким именем:

    const ut = this.updateTime;

    Вместо отдельных элементов можно вставлять разметку:

    this.container.insertAdjacentHTML('beforeend',
      `<div>Последнее изменение: ${ut.getDate()}.${`${ut.getMonth()}`.padStart(2, 0)}</div>` +
      items.map(n => `<div>${n}</div>`).join('')
    );
    Ответ написан
    3 комментария
  • Как составить компонент грамотно?

    0xD34F
    @0xD34F Куратор тега React
    Как Вы думаете, как бы написал опытный реакт-разработчик...
    Я конечно таковым ни разу не являюсь, но всё-таки скажу пару слов.

    проверки через тернарный оператор внутри render?
    Это окей - conditional rendering.

    render() {
        const paths = [
    Из метода render массив paths следует убрать. Может быть, его даже стоит сделать параметром компонента.

    onClick={ () => {this.setState({isOpen: !this.state.isOpen})} }
    Следует сделать метод. Создавать при каждом вызове render новый обработчик - само по себе не очень здорово, ну и ещё этот код повторяется дважды.

    this.props.history.listen(...
    Если предполагается, что во время работы приложения экземпляр компонента будет создаваться несколько раз, то при удалении экземпляра надо снимать обработчик, иначе вывод в консоль задвоится (затроится, зачетверится,...). Сделать это несложно - listen возвращает функцию, снимающую обработчик, так что:
    componentWillMount() {
      this.unlisten = this.props.history.listen(...
    
    componentWillUnmount() {
      this.unlisten();


    <Link className="next_btn"...
    <Link className="prev_btn"...
    Выглядят подозрительно похожими. Я бы рассмотрел вариант сделать под них отдельный компонент, который бы получал isOpen и свойства объектов paths[currPathIndex +/- 1] в качестве параметров.
    Ответ написан
    1 комментарий
  • Как найти индекс элемента массива, удовлетворяющего определённому условию?

    0xD34F
    @0xD34F Куратор тега React
    Это что-то вроде пагинации.

    Очень странно, но допустим:

    const currPathIndex = paths.findIndex(n => n.link === location.pathname);
    const isPrev = currPathIndex !== 0;
    const isNext = currPathIndex !== paths.length - 1;

    Дальше можно отключать кнопки:

    const onClick = e =>
      history.push(paths[currPathIndex + +e.target.dataset.step].link);

    <button disabled={!isPrev} data-step={-1} onClick={onClick}>PREV</button>
    <button disabled={!isNext} data-step={+1} onClick={onClick}>NEXT</button>

    Или не рендерить ссылки:

    {isPrev && <NavLink to={paths[currPathIndex - 1].link}>PREV</NavLink>}
    {isNext && <NavLink to={paths[currPathIndex + 1].link}>NEXT</NavLink>}

    https://jsfiddle.net/ev93d8fj/1/
    Ответ написан
    1 комментарий
  • Почему не перерисовывается компонент?

    0xD34F
    @0xD34F Куратор тега React
    почему он может не перерисовывается когда данные поступают?

    Ни почему.

    Компонент перерисовывается.

    С тем же результатом, что и без данных.

    Потому что забыли .length где-то здесь:

    Object.keys(this.props.landingState) > 0
    Ответ написан
    1 комментарий