Задать вопрос
  • Как отключить скрипт для мобильников?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    подключите такой модуль к проекту:
    const appleDevice     = /iP(hone|od|ad)/;
    const applePhone      = /iPhone/i;
    const appleIPod       = /iPod/i;
    const appleTablet     = /iPad/i;
    const androidPhone    = /(?=.*\bAndroid\b)(?=.*\bMobile\b)/i;
    const androidTablet   = /Android/i;
    const windowsPhone    = /Windows Phone/i;
    const windowsTablet   = /(?=.*\bWindows\b)(?=.*\bARM\b)/i;
    const otherBlackberry = /BlackBerry/i;
    const otherOpera      = /Opera Mini/i;
    const otherFirefox    = /(?=.*\bFirefox\b)(?=.*\bMobile\b)/i;
    const sevenInch       = /(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)/i;
    
    function match(regex, target = navigator.userAgent) {
        return regex.test(target);
    }
    
    export const isAppleDevice = match(applePhone) || match(appleIPod) || match(appleTablet) || match(appleDevice, navigator.platform);
    export const isAndroidDevice = match(androidPhone) || match(androidTablet);
    export const isWindowsDevice = match(windowsPhone) || match(windowsTablet);
    export const isOtherDevice = match(otherBlackberry) || match(otherOpera) || match(otherFirefox);
    export const isSevenInch = match(sevenInch);
    export const isMobileDevice = isAppleDevice || isAndroidDevice || isWindowsDevice || isOtherDevice || isSevenInch;
    export const isEmulator = isMobileDevice && !isWindowsDevice && (match(/Mac/, navigator.platform) || match(/Win32/, navigator.platform));

    далее импортируйте нужный флаг, и проверяйте через if
    Ответ написан
    Комментировать
  • Require.context and lazy-loading?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://webpack.js.org/api/module-methods/#require...
    обратите внимание на 4й необязательный параметр mode, особенно на 'lazy' и 'lazy-once'
    Ответ написан
    4 комментария
  • Вопрос о новых веяниях и требованиях во фронтенде?

    bingo347
    @bingo347
    Crazy on performance...
    Для начала скажу об Html academy, что знаю.
    В начале года звали преподавать у них js + разрабатывать по нему курсы. Сразу скажу, что у меня впервые сложилось положительное впечатление от такого предложения, а не пошел я к ним по причинам не зависящим от них. Во-первых они дают базис, основы без которых Вы просто не сможете нормально разрабатывать, а освоить с этим базисом фреймворк большого труда не составит (про фреймворки ниже напишу).
    Во-вторых, хорошее впечатление у них составили люди, с кем удалось пообщаться, которые занимаются там составлением курсов и преподаванием - все как один не академики-теоретики, а практикующие разработчики с хорошим уровнем (а набирала в преподаватели Html academy в тот момент не ниже сеньера, предлагая соответствующую рынку зп).
    Ну и в-третьих, один раз собеседовал кандидата, имеющего за плечами только Html academy, обычно я негативно отношусь к кандидатом имеющим только курсы за плечами, но тут собеседуемый показал хороший уровень владения js.

    Теперь по фреймворкам.
    Не одному адекватному работодателю не нужен тупой фреймворкописатель без знания языка и нативного api, на которых этот фреймворк основан. В то же время, при знании js и DOM Api - Vue и React осваиваются за неделю, Angular за месяц. А без знания основ, может формочки ваять и сможете, но не больше. Так что учите сначала основы - js и нативное api браузера (DOM, CSSOM, ajax и т.д.), а уже потом беритесь за фреймворк.
    Ответ написан
    Комментировать
  • Как выделить все :focus в css с помощью регулярного выражения?

    bingo347
    @bingo347
    Crazy on performance...
    С регулярками на весь файл скорее всего будут проблемы, много чего может поломаться.
    Я бы сделал так:
    1. поставил бы модуль https://www.npmjs.com/package/css
    2. спарсил бы этим модулем css файл в AST дерево
    3.1. пробежался бы по всем селекторам в AST дереве в поисках селектора с :focus
    3.2. при нахождении нужного селектора, сделал бы что-то с ним (изменил, вырезал (если последний селектор в правиле, нужно вырезать все правило), что-то еще по вкусу)
    4. собрал модулем css AST дерево обратно в css код и записал бы в файл
    Ответ написан
    Комментировать
  • Как задать события в классах ES6?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    // мне кажется, что ждать полной загрузки страницы тут незачем
    document.addEventListener('DOMContentLoaded', () => {
        new Slider({
            images: ".slider__galary img",
            btnPrev: ".btnPrev",
            btnNext: ".btnNext",
            rate: false
        });
    });
    
    // хелпер для прослушивания событий
    class EventListener {
        constructor(ctx, handlers, target) {
            this.ctx = ctx;
            this.handlers = handlers;
            Object.keys(handlers).forEach(event => target.addEventListener(event, this));
        }
    
        handleEvent(event) {
            const {handlers, ctx} = this;
            const {type} = event;
            if(typeof handlers[type] !== 'function') return;
            handlers[type].call(ctx, event);
        }
    }
    
    class Slider {
      construnctor({images, btnPrev, btnNext, rate, time = 1000}) {
            this.images = document.querySelectorAll(images);
            this.i = 0;
            new EventListener(this, {
                click: this.prev
            }, document.querySelector(btnPrev));
            new EventListener(this, {
                click: this.next
            }, document.querySelector(btnNext));
            if(rate) {
                setInterval(() => this.next(), time);
            }
        }
        
        prev() {
            this.images[i].classList.remove("showed");
            this.i--;
            if(this.i < 0){
                this.i = this.images.length - 1;
            }
            this.images[i].classList.add("showed");
        }
    
        next() {
            this.images[i].classList.remove("showed");
            this.i++;
            if(this.i >= this.images.length){
                this.i = 0;
            }
            this.images[i].classList.add("showed");
        }
    }
    Ответ написан
    2 комментария
  • Как впустить в поток, поток получаемый из другого сервиса?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    без знания, что за либа предоставляет youtubeApi сделать адекватно проблематично, но можно сделать универсально:
    const {PassThrough} = require('stream');
    
    const youtubeStream = new PassThrough();
    youtubeApi.downloadVideo(
      'v=4P1-JwZF0Vo&t=4519s',
      chunk => youtubeStream.write(chunk),
      () => youtubeStream.end()
    );
    youtubeStream.pipe(res); // где res - выходной поток к клиенту
    Ответ написан
    1 комментарий
  • Не могу добавить папку в $PATH. Пишет Нет такого файла или каталога. В чем дело?

    bingo347
    @bingo347
    Crazy on performance...
    export PATH="$PATH:/bin/customscripts"
    Ответ написан
    Комментировать
  • Как проверить, что картинка существует?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ну во-первых, присваивание функции в img.load не даст никакого результата, если хотите повесить обработчик события, то нужно присваивать в img.onload

    Во-вторых, данный обработчик работает асинхронно, когда Вы делаете проверку, он еще не выполнился, а выполнится он только тогда, когда картинка загрузится

    Ну и наконец в-третьих, если картинки нет, то событие load не произойдет никогда, нужно проверять еще событие error, чтоб отследить ошибку загрузки, а заодно вешать таймаут, дабы не ждать загрузки вечность

    Проще всего это реализовать с промисами (если нужна поддержка старых браузеров - то добавьте полифил):
    // для начала я вынесу массив с разрешениями из функции, чтоб не создавать его для каждого вызова:
    var resolutions = ['maxresdefault', 'hqdefault', 'mqdefault'];
    function fetch_highest_res(videoid) {
      // сама функция будет возвращать промис, полученный сверткой массива resolutions
      return resolutions.reduce(
        function(promise, resolution) {
          // перехватываем только ошибку загрузки, если была успешная загрузка - просто отдаем ее дальше
          return promise.catch(function() {
            return new Promise(function(resolve, reject) {
              var img = new Image();
              // повесим таймаут в 3 секунды (если надо, поставьте больше), генерирующий ошибку
              setTimeout(reject, 3000);
              // отследим ошибку загрузки
              img.onerror = reject;
              // а в случае успешной загрузки отдадим результат
              img.onload = function() {
                resolve(resolution);
              };
              // и только когда навесили обработчики начинаем загрузку
              img.src = 'https://i.ytimg.com/vi/' + videoid + '/' + resolution + '.jpg';
            });
          });
        },
        // в качестве инициализирующего значения отдаем отклоненный промис
        // так как следующая картинка должна пробоваться только если не получилось загрузить предыдущую
        // а отслеживать мы это будем по ошибке загрузки
        Promise.reject()
      // ну и перехватим случай, если ничего не удалось загрузить
      ).catch(function() { return null; });
    }
    
    // ну и функция теперь у нас возвращает асинхронный результат в виде промиса
    // поэтому и получать его надо соответствующе
    fetch_highest_res('eei-soH5Gx8').then(function(resolution) {
      console.log(resolution); // hqdefault
    });


    P.S. сделал все в es5, ибо мало ли, Вам нужна поддержка старья, а сборкой Вы явно не пользуетесь...
    Ответ написан
  • Правильно ли изучать все и сразу?

    bingo347
    @bingo347
    Crazy on performance...
    учить что-то бесполезно, нужна практика а не зубрежка.
    выкиньте вообще все учебники пылится на полку, они не эффективны, придумайте себе проект и начните его делать, а там где уже попали в ступор - идите в справочники и учебники, так профит будет в разы больше

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

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    function handleClick() {
        $('.photo').removeClass('active-element');
        $(this).addClass('active-element');
        $('.point li').removeClass('active-point').
        filter((index, item) => $(this).data('id') == $(item).data('id')).addClass('active-point');
        $('.about-text p').text($(this).data('text'));
        $('.about-site p').text($(this).data('info'));
        $('.about-site a').text($(this).data('website')).attr("href", "#");
    }
    
    $('.photo').click(handleClick);
    $('.point li').click(function() {
        $('.point li').removeClass('active-point');
        $(this).addClass('active-point');
        handleClick.call(this)
    });
    Ответ написан
    Комментировать
  • Кроссбраузерность Safari?

    bingo347
    @bingo347
    Crazy on performance...
    Кто нибудь знает бесплатные способы посмотреть свою верстку в Safari, если сижу на винде?
    Из бесплатных - только воткнуть хакинтош в виртуалку, но нормально работает только на процессорах от intel (и то не на всех), имеющих аппаратную виртуализацию
    Из бюджетных - взять б/у макбук эир или мак мини

    И стоит ли вообще запариваться по этому поводу
    стоит... сафари на сегодня самый проблемный браузер.

    кроме того еще есть мобильный сафари, с которым проблем еще больше, распространен он тоже больше чем десктопный брат (на iOS по факту нет других браузеров), дебажить его можно только с мака (ну или хака), и Вам по любому понадобится iPhone (опять же подойдет б/у)
    Ответ написан
    Комментировать
  • Как добавить/удалить элемент в блок?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    замените
    if (optionList) {
        $('.total-review-list').append(optionList);
      }
    на$('.total-review-list').html(optionList);
    Ответ написан
    1 комментарий
  • Настроить импорт из window в webpack?

    bingo347
    @bingo347
    Crazy on performance...
    Комментировать
  • Как должна организовываться модульная система?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    модули имеют изолированную область видимости, на то они и модули
    Вам нужно явно поместить chartModule в глобальный объект:
    //module.js
    import  chartModule from '/static/scripts/myScripts/chartModule/myChart.js'; // импортирует функцию для создания графиков
    
    // помещаем chartModule в window, чтоб он был доступен глобально
    window.chartModule = chartModule;
    Ответ написан
  • Как добавить JavaScript после тега?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Я так понимаю, у Вас js-код в виде строки в другом js-коде получается, тут есть несколько вариантов:

    вариант 1, самый простой, создать из строки функцию и выполнить ее:
    const CODE = 'console.log("good");'; // ваш код
    
    (new Function(CODE))(); // создаем из него функцию и сразу вызываем

    вариант 2, подходит только для этапа загрузки страницы, работает только до события DOMContentLoaded у document, просто пишем в поток html кода тег script с нужным кодом. Подойдет так же для выполнения кода в iframe
    const CODE = 'console.log("good");'; // ваш код
    
    document.write('<script>' + CODE + '</' + 'script>');


    вариант 3, тоже с генерацией тега script, но уже работает в любое время, подставляем код как url в src тега script
    const CODE = 'console.log("good");'; // ваш код
    
    const scriptTag = document.createElement('script');
    scriptTag.type = 'application/javascript';
    scriptTag.src = URL.createObjectURL(new Blob([CODE]));
    document.head.appendChild(scriptTag);
    Ответ написан
  • Как проверить что объект существует?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    player1 = new YT.Player('player1', {
      // your config
      events: {
        onReady() {
          // плеер создан
        },
        onError(err) {
          // что-то пошло не так
        }
      }
    }
    Ответ написан
  • Почему не работает крос доменный запрос?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    у Вас стоит опция withCredentials: true - которая говорит браузеру, что Вы хотите отправлять куки стороннему ресурсу. В этом плане более строгая политика CORS:
    1. заголовок ответа Access-Control-Allow-Origin не может быть вилдкард (*), сервер должен отвечать точным origin
    2. должен присутствовать заголовок ответа Access-Control-Allow-Credentials: true

    по итогу сервер должен ответить следующими заголовками:
    Access-Control-Allow-Origin: {request.headers.Origin}
    Access-Control-Allow-Methods: GET, OPTIONS, HEAD
    Access-Control-Allow-Credentials: true

    где {request.headers.Origin} - заголовок Origin из запроса
    Ответ написан
    Комментировать
  • Как свойство экземпляра в VUE сделать реактивным?

    bingo347
    @bingo347
    Crazy on performance...
    Хм, на ум приходит нечто такое:
    const box = new Vue({data: {groups: []}});
    Object.defineProperty(Vue.prototype, '$dataGroups', {
      configurable: true,
      get() { return box.groups; },
      set(value) { box.groups = value; }
    });


    P.S. у Вас разные свойства $dataGroups и $dataGroupsActive
    P.S.S. иметь в прототипе объекты/массивы не очень хорошая практика, лучше сделать подобно тому, как Vuex кидает $store в инстансы, через миксин: https://github.com/vuejs/vuex/blob/dev/src/mixin.js#L22

    UPD: пример с миксином:
    Vue.mixin({
      beforeCreate() {
        const {$options} = this;
        const {parent} = $options;
        if($options.dataGroups) {
          const groups = typeof $options.dataGroups === 'function' ? $options.dataGroups() : $options.dataGroups;
          const box = new Vue({data: {groups}});
          Object.defineProperty(this, '$dataGroups', {
            configurable: true,
            get() { return box.groups; },
            set(value) { box.groups = value; }
          });
          return;
        }
        if(!parent) { return; }
        const descriptor = Object.getOwnPropertyDescriptor(parent, '$dataGroups');
        if(!descriptor) { return; }
        Object.defineProperty(this, '$dataGroups', descriptor);
      }
    });
    Ответ написан
  • Как вырезать строку начинающего с определённого символа?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    если правильно понял:
    console.log(`
    Текст
    # текст 2
    # текст "текст с #" 3
    # текст 4
    # текст 5
    `.match(/^#.*$/gm));
    Ответ написан
    1 комментарий