• Кроссбраузерность 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 комментарий
  • Каким образом можно кешировать изображения?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    О ,я как раз собирался уточнить это) Суть в том ,что на сайте есть достаточно много картинок ,и про проверке сайта на скорость загрузки ,мне посоветовало "кэшировать изображения" ,я начитался в интернете ,что можно начать загрузку всех изображений сразу ,до их открытия пользователем ,путем кэширования. Т.е. страницы открылась ,пользователь еще на самом верху ,а изображения в других местах страницы уже грузятся и когда он до них доходит ,они уже загружены ,как то так )

    Насчет проверки на скорость загрузки - имеется в виду как раз отдавать правильные заголовки для кэширования с сервера, что Вам уже подсказали в комментариях к вопросу.

    Ну а насчет предварительной загрузки изображений до показа их пользователю, понадобится список таких изображений, которые нужно предзагрузить. Сразу скажу, что грузить таким образом изображения, которые уже есть на странице смысла нет, но вот изображения для всяких модалок таким образом грузить вполне себе резонно:
    // сделаем функцию, ждущую загрузку основной страницы,
    // чтоб не мешать ей при загрузке дополнительных картинок:
    function waitWindowLoad() {
      if(document.readyState === 'complete') {
        return Promise.resolve();
      }
      return new Promise(resolve => {
        const listener = () => {
          window.removeEventListener('load', listener);
          resolve();
        };
        window.addEventListener('load', listener);
      });
    }
    
    // массив url подгружаемых картинок
    [
      '/images/1.png',
      '/images/2.png',
      '/images/3.png'
    ].reduce((promise, url) => promise.then(() => new Promise(resolve => {
      // грузим картинки по очереди
      const img = new Image();
      img.onload = img.onerror = resolve;
      img.src = url;
    })), waitWindowLoad());
    Ответ написан
  • Почему у меня данные не меняются?

    bingo347
    @bingo347
    Crazy on performance...
    Во-первых, selected у Вас явно объект, а не массив, поэтому в data меняем строку
    selected: []
    на
    selected: {}

    Во-вторых, vue не умеет отслеживать данные, которых изначально нет в data и нужно явно указывать, что мы их меняем, поэтому в методе onSelect меняем строку
    this.selected[day] = !this.selected[day];
    на
    this.$set(this.selected, day, !this.selected[day]);

    https://ru.vuejs.org/v2/api/#vm-set
    Ответ написан
  • Веб студии просто не выставляют многие работы в портфолио или в свободное время на стройке работают?

    bingo347
    @bingo347
    Crazy on performance...
    Когда я на старте своей карьеры работал в веб-студии (давно было, но не думаю, что что-то кардинально поменялось), сайты клепались пачками, по несколько штук в день. Естественно 90% из них были как под копирку, отличаясь лишь контентом. Смысла выставлять 100500 однотипных сайтов в портфолио просто нет
    Ответ написан
    Комментировать
  • Как сделать вывод в цикле один раз?

    bingo347
    @bingo347
    Crazy on performance...
    int[,] a = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
    bool s = true;
    for (int i = 0; s && i < a.GetLength(0); ++i)
      for (int j = 0; s && j < a.GetLength(1); ++j)
        s = s && a[i, j] == a[j, i];
    Console.WriteLine(s ? "Симметрична" : "Ne simmetrichna");
    Ответ написан
    2 комментария
  • Почему не устанавливается плагин Sass для Gulp?

    bingo347
    @bingo347
    Crazy on performance...
    Если внимательно почитать вывод в консоль, то можно увидеть, что проблема с правами, а все дело в том, что не нужно запускать npm install из под sudo

    итак, для начала следует из под рута снести папку модуля:
    sudo rm -rf /Users/ilyasidorchik/PhpstormProjects/pigna/node_modules/node-sass

    затем еще раз выполнить npm install node-sass gulp-sass --save-dev только на этот раз без sudo
    Ответ написан
    1 комментарий
  • Как сделать вывод больших чисел в сокращенном варианте?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const SHORTCUT_SUFFIXES = ['K', 'M', 'B', 'T', 'Q', 'P'];
    function shortcutNumber(num) {
      const normalized = Number(num).toFixed(0);
      const expPosition = normalized.indexOf('e');
      const dotPosition = normalized.indexOf('.');
      const hasExponent = expPosition !== -1;
      const exponent = parseInt(normalized.slice(expPosition + 2));
      const len = hasExponent ? expPosition + exponent : normalized.length;
      if(len < 4) return String(num);
      const suffixNumber = Math.floor((len - 1)  / 3);
      const suffix = SHORTCUT_SUFFIXES[suffixNumber - 1];
      const fullNumber = (hasExponent
        ? normalized.slice(0, expPosition).replace('.', '')
          + '0'.repeat(exponent - (dotPosition === -1 ? 0 : expPosition + dotPosition + 1))
        : normalized
      );
      if(!suffix) {
        // число о-о-очень большое, больше чем мы суффиксов задали...
        return fullNumber.slice(0, -(SHORTCUT_SUFFIXES.length * 3))
          + SHORTCUT_SUFFIXES[SHORTCUT_SUFFIXES.length - 1];
      }
      return fullNumber.slice(0, -(suffixNumber * 3)) + suffix;
    }
    Ответ написан
    Комментировать
  • Как сортировать обьекты по дате ( по возрастанию )?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    array.sort((a, b) => {
      if(a.var !== true || b.var !== true) return 0;
      return a.date - b.date;
    });
    Ответ написан
    Комментировать
  • Существует ли аналог mail() для node.js?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Ответ написан
    Комментировать
  • Какую спецификацию EcmaScript учить?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Все, они не заменяют, а дополняют друг друга
    Ответ написан
    Комментировать
  • Как с технической точки зрения сделаны сервисы генерирующие виджеты?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Поделюсь как это сделано у нас, надеюсь поможет
    во-первых, сайт заводится в нашей БД и ему присваивается id
    во-вторых, сайт вставляет к себе наш код, он небольшой, но делает две вещи:
    1. создает временную функцию в window - которая совпадает по имени с нашей функцией запуска, но просто сохраняет себе в массив все вызовы и их аргументы
    2. начинает загрузку js-кода нашего виджета
    в-третьих, сайт вызывает нашу функцию запуска, куда передает свой id из нашей БД и некоторые параметры

    когда наш основной js загрузился, он делает следующее:
    1. переписывает в window временную функцию собирающую аргументы на настоящую, которая запускает вставку виджета
    2. если собранны запуски до этого момента - запускает их в настоящей функции запуска
    3. функция запуска дергает сервер и запрашивает данные по id сайта
    4. вставляем на страницу iframe и в нем рисуем виджет

    на деле все чуть сложнее, но общий принцип такой
    Ответ написан
    2 комментария
  • Как получить статус отправки сообщения через WebSocket?

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