• Как в typescript объединить ключи, и если появляются повторы, то сделать объединение типов?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Запилил такой вариант.

    Поддерживаются вложенные объекты и массивы (кортежи), см. пример. Глубина рекурсии произвольная, но результат получается здоровенный, если много всего.

    Решение влоб: сначала находим все пути до простых значений, потом по множеству этих путей собираем объект.
    Ответ написан
    3 комментария
  • Стоит ли использовать lodash сейчас?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Я так понимаю все что предлагает лодаш уже реализовано нативно

    Не понимаете.
    Ответ написан
    Комментировать
  • Есть ли оверхед/нагрузка на большое количество обработчиков событий?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Обработчиков у вас в любом случае 200 вешается.
    Вся разница в том, что в первом случае они ссылаются на двести функций, а во втором на одну.
    Создание функции требует определённых ресурсов, поэтому оверхед есть. Будет ли он заметным — это другой вопрос. Ответ на него зависит от того, что на самом деле в вашем коде происходит. На компьютере вы, скорее всего, разницы никогда не почувствуете, а вот на очень слабом телефоне при огромном количестве функций может начать тормозить.

    P.S. Проще использовать делегирование в таких случаях.
    Ответ написан
    Комментировать
  • Как можно переводить минут/секунд/часы в число если получаю не в формате числа?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getSeconds = str =>
      [
        [ 'де?н', 24 * 60 * 60 ],
        [  'час',      60 * 60 ],
        [  'мин',           60 ],
        [  'сек',            1 ],
      ].reduce((acc, n) => {
        return acc + (str.match(RegExp(`\\d+(?=\\s+${n[0]})`)) ?? 0) * n[1];
      }, 0);
    
    
    getSeconds('2 часа 22 секунды') // 7222
    getSeconds('99 минут') // 5940
    getSeconds('1 час 1 минута 1 секунда') // 3661
    getSeconds('1 день 23 часа 59 минут 60 секунд') // 172800
    getSeconds('2 дня') // 172800
    getSeconds('546 секунд и ещё 2 минуты') // 666
    Ответ написан
    2 комментария
  • Ошибка при запуске таска Gulp?

    6528d8858f8a4901424549.png
    Ответ написан
    Комментировать
  • Как решить долгий запрос blob?

    @risejs
    У тебя видео скачивается полностью. Если хочешь по частям, то надо сделать подобие потока. Blob для этого не подходит, то что в ссылке написано blob: не значит что URL.createObjectURL() принимает только Blob, там еще есть MediaSource.

    Потоковые медиа в браузерах работают через Media Source API. Видео для него должно соответствовать определенным требованиям, например фрагментированный mp4. Видео по твоей ссылке таким не является. Можно проверить здесь mp4info.

    Если для транспорта используется fetch или XMLHttpRequest, то есть парочка относительно простых способов это реализовать:

    1. Через тип ответа ArrayBuffer и заголовок запроса Range. В fetch поддерживается через response.arrayBuffer(), в XMLHttpRequest через responseType='arraybuffer'.
    Например.

    2. Через тип ответа ReadableStream (Streams API). В fetch поддерживается через response.body, в axios и других xmlhttprequest-основанных библиотеках не поддерживается. Также для Streams API требуется протокол HTTP/2+.
    Например 1, 2, 3, 4.

    Краткие примеры:
    const rangeVideo = async (player, mimeCodec, resource) => {
        const mediaSource = new MediaSource;
        player.src = URL.createObjectURL(mediaSource);
        await new Promise(resolve => mediaSource.onsourceopen = resolve);
        URL.revokeObjectURL(player.src);
        const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
    
        const response = await fetch(resource, { method: 'HEAD' });
        const contentLength = response.headers.get('Content-Length');
        const segmentLength = 1 * 1024 * 1024;
        let fetchedLength = -1;
    
        while (true) {
            if (fetchedLength >= contentLength) break;
            const response = await fetch(resource, {
              headers:{'Range':`bytes=${fetchedLength+1}-${fetchedLength+=segmentLength}`}
            });
            const value = await response.arrayBuffer();
            sourceBuffer.appendBuffer(value);
            await new Promise(resolve => sourceBuffer.onupdateend = resolve);
            //console.count();
            //await delay(2000);
        }
    };
    
    const streamVideo = async (player, mimeCodec, resource) => {
        const mediaSource = new MediaSource;
        player.src = URL.createObjectURL(mediaSource);
        await new Promise(resolve => mediaSource.onsourceopen = resolve);
        URL.revokeObjectURL(player.src);
        const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
    
        const response = await fetch(resource);
        const readableStream = response.body;
        const reader = readableStream.getReader();
    
        while (true) {
            const { value, done } = await reader.read();
            if (done) break;
            sourceBuffer.appendBuffer(value);
            await new Promise(resolve => sourceBuffer.onupdateend = resolve);
            //console.count();
        }
    };
    
    //const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
    
    const data = [
        document.querySelector('video'),
        'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
        'https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4',
    ];
    
    //rangeVideo(...data);
    //streamVideo(...data);
    Ответ написан
    Комментировать
  • Проблема с цветом видео в разных браузерах?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Конечно сталкивались, и простого решения конкретной проблемы нет: видео это немного отдельный поток и там всегда могут быть свои настройки отображения.

    Решения есть следующие:
    1. Делать видео сразу с прозрачностью, а не с бэкграундом, современные браузеры это поддерживают:
    2. Рисовать видео на canvas, программно подгоняя фон.
    3. Накладывать SVG фильтр на видео, который погонит фон.
    Ответ написан
    Комментировать
  • Как сортировать по индексу другого массива в js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сортировать по indexOf( ID ) в массиве, задающем порядок сортировки:
    var data = [
      {ID: 1, country: 'England'},
      {ID: 4, country: 'USA'},
      {ID: 9, country: 'Russia'},
      {ID: 5, country: 'Germany'},
      {ID: 6, country: 'France'},
    ];
    
    const order = [5,1,9,6,4];
    
    data.sort((a,b) => order.indexOf(a.ID) - order.indexOf(b.ID));
    
    /* [
      {"ID":5,"country":"Germany"},
      {"ID":1,"country":"England"},
      {"ID":9,"country":"Russia"},
      {"ID":6,"country":"France"},
      {"ID":4,"country":"USA"}]
    */


    На больших массивах для ускорения:
    1. добавить в исходный массив новое поле с порядковым номером, который каждый элемент должен занять после сортировки;
    2. отсортировать по этому полю.

    Так будет быстрее, чем на каждой операции сравнения двух элементов искать их индексы во втором массиве.
    data = data.map( e => {e.sortBy = order.indexOf(e.ID); return e;} );
    data.sort( (a,b) => a.sortBy - b.sortBy);
    Ответ написан
    Комментировать
  • Как изменять размер элемента при наведении на его край курсора мыши?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    окей яндекс: custom resizable element
    https://habr.com/ru/articles/321612/
    Ответ написан
    5 комментариев
  • Почему в теле цикла не отображается консоль?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Когда вы сравниваете число с массивом, какой вы ожидаете результат?
    - i while(<= arr){
    + i while(<= arr.length){

    Более того, цикл у вас бесконечный, потому что i в нём не изменяется, так что это даже и хорошо, что он не запускается.
    Ответ написан
    1 комментарий
  • Замыкания не существует?

    Stalker_RED
    @Stalker_RED
    Я немного добавил наглядности
    function one() {
      const oneVar = 'Hello!'
      let counter = 0;
      console.log('функция one работает прямо сейчас, в счетчике', counter)
    
      function two() {
        console.log(oneVar, ++counter)
      }
      
      console.log('функция one почти завершилась, в счетчике все еще ', counter);
      return two
    }
    
    const three = one();
    console.log('функция one точно завершилась, даже return сработал');
    console.log('в переменной three сейчас функция two()');
    console.log(three);
    
    
    three();
    three();
    three();
    console.log('обожемой, мы видим как менялась переменная в уже завершенной функции. чераная магия? нет - это называется замыкание!');

    выхлоп:
    "функция one работает прямо сейчас, в счетчике", 0
    "функция one почти завершилась, в счетчике все еще ", 0
    "функция one точно завершилась, даже return сработал"
    "в переменной three сейчас функция two()"
    function two() {
      console.log(oneVar, ++counter)
    }
    "Hello!", 1
    "Hello!", 2
    "Hello!", 3
    "обожемой, мы видим как менялась переменная в уже завершенной функции. чераная магия? нет - это называется замыкание!"
    Ответ написан
    Комментировать
  • Почему обработчик реагирует на событие, случившееся до его установки?

    0xD34F
    @0xD34F Куратор тега React
    Я так понимаю, вот она, причина, подъехала с версией 18.0.0:

    Consistent useEffect timing: React now always synchronously flushes effect functions if the update was triggered during a discrete user input event such as a click or a keydown event.

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

    При добавлении задержки, данная проблема уходит

    Можете ещё попробовать ловить событие в фазе погружения:

    document.addEventListener('click', handleOutsideClick, true);
    return () => document.removeEventListener('click', handleOutsideClick, true);
    Ответ написан
    Комментировать
  • Какая функциональная разница между этими подходами создания объектов в JS?

    Xuxicheta
    @Xuxicheta
    инженер
    допустим User это функция-конструктор, или класс.
    user = new User()

    будет создан объект, у которого есть свойство __proto__ в котором лежит объект, состоящий из одного свойства constructor, которая и есть ваша функция User. (Ну типа такой { constuctor: User }. Если писать через class то мы конструктор явно прям зададим. )
    Этот же объект лежит по адресу User.prototype, т.е.
    user.__proto__ === User.prototype
    Этот объект создается для любой объявленной функции (вообще не обязан, но в V8 вроде так), и например User.prototype.constructor === User

    Что такое метод класса, это функция по адресу User.prototype.sayHi (оно же лежит в user.__proto__.sayHi)
    Потом, когда мы пишем user.sayHi js проходит по цепочке из свойств __proto__ и ищет там эту функцию, вызывает ее и передает в качестве контекста (this) наш объект user.

    А теперь посмотрим разницу с вашим
    function User(x,y){
    let name = x;
    let age = y;
    
    return {
    name : name,
    age : age,
    sayHi: function(){
    console.log("My name is " + this.name);
    }
    }
    }


    тут все поля и функции лежат в одном объекте, который имеет только дефолтный __proto__ Object.prototype, автоматически присваиваемый при создании объекта через объектный литерал.
    При вызове функции несколько раз будут созданы несколько никак не связанных объекта. Прототип у них Object, это единственное что их роднит. Функции будут созданы каждый раз заново.
    user1.sayHi !== user2.sayHi
    Оператор instanceof не найдет у них общего предка User.

    Вот в этом и разница. Можно ли так писать? Можно, только зачем?
    Как назвать? Ну допустим функция-фабрика объектов. (не путатьс классом-фабрикой и со статическим фабричным методом, там создаются инстансы классов).

    Найдёте теперь сами разницу в ваших примерах 1 и 2?
    А так же почему в примере 1 new User() и просто User() дадут совершенно разный результат? И как сделать чтоб было одинаково?
    Ответ написан
    1 комментарий
  • Кроссбраузерность?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Да.
    Ответ написан
  • Как равномерно заполнить 3 массива с учетом высоты элементов?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ошибка в том что columnHeight нужно обновлять по тому же индексу, что и columns.
    Ну еще есть проблемы с тем, что исходные данные не упорядочены, а значит массивы будут заполняться не равномерно. Притом сортировать лучше по убыванию.
    Так же, если нужен оригинальный порядок, то его нужно сохранить, а потом так же восстанавливать сортировкой.

    // Сохраняем исходные индексы и сортируем по высоте по убыванию
    const preparedData = data
        .map((e, i) => ({i, e}))
        .sort((a, b) => b.e.height - a.e.height);
    
    for (const el of preparedData) {
        const { height } = el.e;
        // тут никогда не вернет -1, так как мы ищем элемент который точно есть в массиве - минимальный
        const index = columnHeight.indexOf(Math.min(...columnHeight));
        // обновляем данные массивов по выбранному индексу
        columnHeight[index] += height;
        columns[index].push(el);
    }
    
    // нормализуем columns
    for (let i = 0; i < columns.length; ++i) {
        // восстановим исходный порядок, отсортировав по сохраненному индексу по возрастанию
        columns[i].sort((a, b) => a.i - b.i);
        // избавимся от сохраненных индексов, оставив только исходные объекты
        columns[i] = columns[i].map(({ e }) => e);
    }
    Ответ написан
    Комментировать
  • Как работает этот JS со своим if?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    - if (duplicates.length = 0) {
    + if (duplicates.length === 0) {
    Ответ написан
    2 комментария
  • Что произошло с шрифтом?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Без кода можно только гадать, что произошло в этом конкретном случае, но на ум сразу приходит свойство font-palette из CSS. Оно уже начинает поддерживаться в современных браузерах и некоторые энтузиасты его используют.

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

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Надо явно создать union:
    type ITableColumn<
      DataInterface extends object, 
      Keys extends keyof DataInterface = keyof DataInterface
    > = {
      [K in Keys]: {
        key: K;
        title: React.ReactNode;
        hasSort?: boolean;
        render?: (item: DataInterface[K]) => React.ReactNode;
      }
    }[Keys];
    Ответ написан
    4 комментария