Ответы пользователя по тегу JavaScript
  • Наследование от Date?

    rockon404
    @rockon404
    Frontend Developer
    Проблема в том, что в методах прототипа Date идет проверка на то, что передан экземпляр даты. Причем проверка идет не по цепочке прототипов.
    Старый исходный код V8:
    function DateGetTime() {
      CHECK_DATE(this);
      return UTC_DATE_VALUE(this);
    }

    Кто-то писал, что CHECK_DATE имеет следующую реализацию:
    CHECK_DATE(arg) = (%_ClassOf(arg) === 'Date' ? %_ValueOf(arg) : ThrowDateTypeError());


    Тем не менее, сейчас все это переписано на C++.

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

    Вариант решения этой проблемы, изменить цепочку прототипов экземпляра:
    function SpaceDate(...args) {
      var date;
      date = new Date(...args);
      date.__proto__ = SpaceDate.prototype;
      return date;
    }
    
    SpaceDate.prototype.__proto__ = Date.prototype;
    
    SpaceDate.prototype.test = function() {
      return this;
    };

    Возвращаться будет объект Date, а цепочка прототипов будет с вашими методами. На прототип оригинального объекта Date это никак не повлияет.
    Ответ написан
    2 комментария
  • Как устранить проблему с путями при сборке с webpack?

    rockon404
    @rockon404
    Frontend Developer
    Если экспортируете кнопку c помощью export default:
    import DefaultButton from '../../Buttons/Default';
    Обратите внимание, что переход на директорию выше обозначается двумя точками, а не тремя.
    Ответ написан
  • Неадекватная работа блока input, как исправить?

    rockon404
    @rockon404
    Frontend Developer
    Так все input с одинаковым name будут принимать значение измененного:
    $(document).on('focusout', 'input', function(){
      var name = $(this).attr('name');
      var value = $(this).val();
    
      $('input[name=' + name + ']').val(value);
    });


    Демо.
    Ответ написан
    1 комментарий
  • Тестирование в React, в чем ошибка?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Как минимум у вас при попытке вызова render выпадает ошибка:
    Cannot convert undefined or null to object
    Так как вы не передаете total в store.
    Зачем вам вообще оборачивать компонент в connect при тестировании?
    Попробуйте изменить файл компонента так:
    import React from 'react';
    import { connect } from 'react-redux';
    
    export class Balance extends React.Component {
      // some code
    }
    
    const mapStateToProps = ({ total }) => ({ total });
    
    export default connect(mapStateToProps)(Balance);

    То, что вы назвали компонент BalanceCont, семантически неверно. Так как контейнер это HOС поверх вашего компонента, вызовом connect вы оборачиваете компонент в контейнер.

    Теперь вы можете импортировать компонент для тестов, как:
    import { Balance } from './Balance';
    А контейнер в приложение как:
    import Balance from './Balance';

    Измененный тест:
    import React from 'react';
    import { shallow, mount } from 'enzyme';
    import { expect } from 'chai';
    import { Balance } from '../app/containers/balance/src/balance';
    
    describe('<Balance />', () => {
      it('Balance test', function () {
        
        const mockTotal = { /* mock code */ };
        
        const wrapper = shallow(<Balance total={mockTotal} />);
        expect(wrapper.contains(<h3>Мои балансы</h3>)).to.equal(true);
      });
    });
    Ответ написан
    2 комментария
  • Какой плагин js используется на сайте для отображения графика котировок?

    rockon404
    @rockon404
    Frontend Developer
    Эта библиотека.
    Вообще если вбить в поиск traiding charts js, можно найти много готовых решений.
    Ответ написан
    Комментировать
  • Есть триггер анимации onClick, как убрать его и сделать так что бы анимация воспроизводилась при onLoad?

    rockon404
    @rockon404
    Frontend Developer
    imagesLoaded(document.body, { background: true }, () =>
      document.body.classList.remove('loading'));
    
    const piecesObj = new Pieces(document.querySelector('.slideshow > .pieces'), {
      pieces: {rows: 22, columns: 20},
      delay: [0,60],
      hasTilt: true,
      tilt: {
        maxRotationX: -1, 
        maxRotationY: -1, 
        maxTranslationX: -5, 
        maxTranslationY: -2
      }
    });
    
    let isAnimating = false;
    
    const openImage = () => {
      isAnimating = true;
    
      piecesObj.animate({
        duration: 400,
        easing: 'easeOutQuad',
        autoplay: true,
        delay: (t,i,l) => {
          return parseInt(t.dataset.row) * parseInt(t.dataset.delay);
        },
        translateX: (t,i) => {
          return anime.random(-500,500)+'px';
        },
        translateY: (t,i) => { 
          return anime.random(-800,-200)+'px';
        },
        rotateZ: (t,i) => { 
          return anime.random(-45,45)+'deg';
        },
        opacity: 0,
        complete: () => {
          piecesObj.setImage(imgsrc);
    
          piecesObj.animate({
            duration: 500,
            easing: [0.3,1,0.3,1],
            delay: (t,i,l) => {
              return parseInt(t.dataset.row) * parseInt(t.dataset.delay);
            },
            translateX: 0,
            translateY: () => {
              return [anime.random(200,800)+'px','0px'];
            },
            rotateZ: 0,
            opacity: {
              value: 1,
              duration: 500,
              easing: 'linear'
            },
            complete: () => {
              isAnimating = false;
            }
          });
        }
      });
    };
    
    document.addEventListener('DOMContentLoaded', openImage);
    Ответ написан
  • Как исправить ошибку при импорте json файла?

    rockon404
    @rockon404
    Frontend Developer
    Смею предположить, что ошибка во вложенных объектах в массиве anotherData. Все ключи должны быть в кавычках и не должно быть лишних запятых. Валидатор вам в помощь.
    Ответ написан
  • Можно ли переходить на изучение фреймворков?

    rockon404
    @rockon404
    Frontend Developer
    Изучайте React. Приложения на ванильном JS писать не надо, не повторяйте ошибки разработчиков из 2014 года.
    Ответ написан
  • Как при клике на элемент добавить ему класс, а у всех соседей удалить?

    rockon404
    @rockon404
    Frontend Developer
    Вариант без делегирования.
    Ответ написан
    Комментировать
  • Как сделать печать в верхнем регистре только буквы "a"?

    rockon404
    @rockon404
    Frontend Developer
    Есть более простой путь:
    var div = document.getElementById("div3");
    var input = document.getElementById('value_for_div3');
    
    input.addEventListener('keyup', function(e) {
      div.innerHTML = this.value.replace(/а/g, 'A');
    });


    В данном примере заменяется только "а" из кириллицы.

    Если надо заменять и из кириллицы и из латиницы, то регулярное выражение заменяем на:
    div.innerHTML = this.value.replace(/(a|а)/g, '$1'.toUpperCase());

    Символы на вид одинаковые, но коды у них разные.

    Демо.
    Ответ написан
  • Api запрос из react приложения выполняется только один раз, что делать?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    render() {
      const { res } = this.state;
      const shouldFlimDisplayShown = !!res;
    
      return (
        <div>
          <form onSubmit={this.handleSubmit}>
            <label htmlFor="title">Enter title</label>
            <input id="title" name="title" type="text" />
            <button>Send data!</button>
          </form>
          {shouldFlimDisplayShown && <FilmDisplay filmName={res}/>}
       </div>
      );
    }


    import React from 'react';
    
    class FilmDisplay extends React.Component {
       constructor() {
        super();
    
        this.state = {
          filmData: null
        };
      }
    
      componentDidMount() {
        this.fetchMovie();
      }
    
      componentDidUpdate(prevProps) {
        if (prevProps.filmData !== this.props.filmData) {
          this.fetchMovie();
        }
      }
     
      fetchMovie() {
        const { filmName } = this.props;
        const URL = "http://www.omdbapi.com/?t=" + filmName + "&apikey=6540f2ec&";
    
        fetch(URL).then(res => res.json()).then(json => {
          this.setState({ filmData: json });
        });
      }
    
      render() {
        const { filmData } = this.state;
    
        if (!filmData) return <div>Loading</div>;
      
        return <div>{JSON.stringify(filmData)}</div>;
      }
    }
    
    export default FilmDisplay;
    Ответ написан
    Комментировать
  • Почему код выполняется параллельно?

    rockon404
    @rockon404
    Frontend Developer
    В вашем случае, скорей всего, opacity меняется за тысячные доли секунды и срабатывает remove.
    Демо.
    Все шаги выполнения в консоли. На моей рабочей машине opacity меняется с 1 до 0 за 0.005 секунды. Представьте насколько это мало.
    Код синхронный. Выполняться параллельно он не может.
    Ответ написан
  • Как получить данные из массива json в JavaScript?

    rockon404
    @rockon404
    Frontend Developer
    ES5:
    var wor = 'alesh.3';
    var key = 'last30m';
    
    var record = json.data.rows.find(function(el) {
      return el.wor === wor;
    });
    
    var value = record ? record[key] : null;


    ES6:
    const wor = 'alesh.3';
    const key = 'last30m';
    
    const { data: { rows } } = json;
    
    const record = rows.find(el => el.wor === wor);
    const value = record ? record[key] : null;
    Ответ написан
    2 комментария
  • Почему ошибка при установке prettier?

    rockon404
    @rockon404
    Frontend Developer
    ставьте плагин eslint-plugin-react. Дополнительно если не установлены:
    eslint
    babel-eslint
    eslint-plugin-jsx-a11y
    eslint-plugin-import
    eslint-config-prettier
    eslint-config-airbnb
    eslint-plugin-prettier
    Добавляйте так:
    {
      "extends": [
        "airbnb",
        "prettier",
        "prettier/react"
      ],
      "plugins": [
        "prettier"
      ],
      "parser": "babel-eslint",
      "parserOptions": {
        "ecmaFeatures": {
          "jsx": true
        }
      },
      "env": {
        "browser": true,
        "node": true
      },
      "rules": {
        "no-plusplus": 0,
        "no-confusing-arrow": 0,
        "no-restricted-syntax": 0,
        "guard-for-in": 0,
        "class-methods-use-this": 0,
        "jsx-a11y/no-static-element-interactions": 0,
        "jsx-a11y/anchor-is-valid": 0,
        "react/no-danger": 0,
        "react/prop-types": 0,
        "react/jsx-filename-extension": 0,
        "react/jsx-curly-brace-presence": ["error", { "props": "never", "children": "never" }],
        "import/no-unresolved": ["error", { "commonjs": true }],
        "import/extensions": 0,
        "import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
        "import/prefer-default-export": 0,
        "prettier/prettier": ["error", {
          "singleQuote": true,
          "trailingComma": "all"
        }]
      }
    }


    Правила настройте под себя.

    Если хотите precommit проверку, то поставьте lint-stаged и husky, и добавьте следующие строки в package.json:
    "scripts": {
        // ваши скрипты
        "precommit": "./node_modules/.bin/lint-staged",
      },
      "lint-staged": {
        "**/*.js": [
          "./node_modules/.bin/prettier --write",
          "./node_modules/.bin/eslint --fix",
          "./node_modules/.bin/stylelint './app/**/*.js'", // если используете  css in js
          "git add"
        ]
      },

    Теперь перед каждым вашим коммитом код будет приводиться в порядок на автомате если это возможно. И прерывать коммит ошибкой если нарушены правила.
    Ответ написан
  • Живая перезагрузка Hot Module Replacement для нативного JavaScript не работает?

    rockon404
    @rockon404
    Frontend Developer
    Вариант 1. Горячая замена самого модуля:
    const greetings = 'Hello, friend';
    let h1;
    
    function say() {
      h1 = document.createElement('h1');
      h1.innerHTML = greetings;
      document.body.appendChild(h1);
    }
    
    say();
    
    if (module.hot) {
      module.hot.dispose(() => {
        document.body.removeChild(h1);
      });
    
      module.hot.accept();
    }


    Вариант 2. Горячая замена дочернего модуля:
    Добавьте модуль greetings.js:
    const greetings = 'Hello, friend';
    
    export default greetings;

    и измените основной модуль так:
    import './styles.css';
    
    let greetings = require('./greetings').default;
    let h1;
    
    function say() {
      h1 = document.createElement('h1');
      h1.innerHTML = greetings;
      document.body.appendChild(h1);
    }
    
    say();
    
    if (module.hot) {
      module.hot.accept('./greetings', () => {
        greetings = require('./greetings').default;
        document.body.removeChild(h1);
        say();
      });
    }

    Если не используется транспиляция модулей из ES6 в CommonJS, то должно работать и так:
    import './styles.css';
    import greetings from './greetings';
    
    let h1;
    
    function say() {
      h1 = document.createElement('h1');
      h1.innerHTML = greetings;
      document.body.appendChild(h1);
    }
    
    say();
    
    if (module.hot) {
      module.hot.accept('./greetings', () => {
        document.body.removeChild(h1);
        say();
      });
    }
    Ответ написан
    6 комментариев
  • Как убрать eslint warnings одной командой?

    rockon404
    @rockon404
    Frontend Developer
    Поставьте prettier.
    Добавьте его в .eslintrc:
    {
      "extends": [
        "airbnb",
        "prettier",
      ],
      "plugins": [
        "prettier"
      ],
      "parser": "babel-eslint"
    }


    Исправить код можно командой:
    prettier --write
    Ответ написан
    2 комментария
  • Как собрать заготовку на webpack под react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    А вас не смущает, что в руководстве первый webpack, а у вас четвертая версия? Остальное даже не смотрел. Ищите, что-нибудь посвежей, c тех пор как вышла эта статья многое сильно изменилось.
    На github полно готовых боилерплейтов на любой вкус. В англоязычном сегменте полным полно свежих статей.
    Ответ написан
    Комментировать
  • Укажите, пожлуйста, ошибку в этом коде. Где она?

    rockon404
    @rockon404
    Frontend Developer
    Смотрите как это работает. Цель алгоритма вывести простые числа в диапазоне от 2 до 10. Это 2, 3, 5 и 7.
    Простое число это число которое делится лишь на само себя и единицу.
    Следовательно для всех случаев когда i % j == 0 приj >=2 && j < i(i делится на j без остатка при значениях j от 2 и выше, но меньше i) число i не является простым и мы нам надо выйти из итерации цикла, но не внутреннего, в котором мы в данный момент находимся, а внешнего, так как нас больше текущее значение i не интересует. Для этого используется метка main. Вызов continue main; переносит нас на следующую итерацию внешнего цикла.
    Ответ написан
  • Можно ли при обработке события submit формы, узнать введённые данные?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    class Example extends Component {
      state = {
        inputValue: '',
      };
    
      handleChange = e => { 
        const { name, value } = e.target;
        
        this.setState({
          [name]: value,
        });
      };
    
      handleSubmit = e => {
        e.preventDefault();
        //  получить состояние формы можно обратившись к this.state
      };
    
      render() {
        const { inputValue } = this.state;
    
        return (
          <form onSubmit={this.handleSubmit}>
            <input
              name="inputValue"
              value={inputValue}
              onChange={this.handleChange}
            />
            ...
          </form>
        );
      }
    Ответ написан
    Комментировать
  • Почему не работает оператор сравнения === в JS?

    rockon404
    @rockon404
    Frontend Developer
    prompt возвращает string при нажатии Ok и null при нажатии Отмена:
    var x = prompt("введите число");
    console.log(typeof x); // string

    Можно переписать так если надо просто приводить к числу:
    var x = +prompt("введите число");
    console.log(typeof x); // number при условии, что строку можно привести к числу

    Строгое равенство при сравнении разных типов всегда возвращает false:
    '0' === 0 // false

    Если вам надо делать проверки на нажатие Отмена, ввод пустой строки или нечислового значения, приведение стоит делать после этих проверок:
    var input = prompt('Введите число: ');
    
    if (input === '') {
      alert('Пустая строка');
    } else if (input === null) {
      alert('Вы нажали "Отмена"');
    } else if (Number.isNaN(+input)) {
      alert('Вы ввели не число');
    } else if (+input === 0) {
      alert('Вы ввели 0');
    } else if (+input > 0) {
      alert('Вы ввели число больше 0');
    } else {
      alert('Вы ввели число меньше 0');
    }
    Ответ написан
    8 комментариев