Задать вопрос
  • Каким образом можно кешировать изображения?

    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 нет такого встроенного механизма, но никто не мешает реализовать такое самостоятельно
    Ответ написан
  • Нужно ли информировать по правилам GDPR об использовании IndexedDB, когда Cookies фактически не используются?

    bingo347
    @bingo347
    Crazy on performance...
    Нужно информировать пользователя если Ваш ресурс либо третья сторона посредством Вашего ресурса, хранит любые данные, в любом хранилище, позволяющие идентифицировать пользователя в дальнейшем.
    То есть:
    храним токен авторизации (в куках, localStorage, indexedDB или еще где-то) - уведомляем
    храним id истории поиска - уведомляем
    подключили яндекс метрику, гугл аналитику, гугл таг менеджер, скрипты рекламных сетей - уведомляем
    ну и т.д.
    Ответ написан
    1 комментарий
  • Как получить дату на английском?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    new Date().toLocaleString('en', {timeZoneName: 'long'})

    https://developer.mozilla.org/ru/docs/Web/JavaScri...
    Ответ написан
    Комментировать
  • Как разбивать параграф построчно?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    разбиваем в HTML-строку:
    function text2HTML(text) {
      return text.split('\n').map(line => `<div>${line}</div>`).join('');
    }


    разбиваем в DOM фрагмент, который потом можно будет вставить на страницу через appendChild:
    function text2DOMFragment(text) {
      return text.split('\n').reduce((frag, line) => (frag
        .appendChild(document.createElement('div'))
        .appendChild(document.createTextNode(line)),
      frag), document.createDocumentFragment());
    }
    Ответ написан
  • Как и по какому принципу работает внедрение рекламы на сайт Wordpress?

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

    Если хотите текстовую рекламу: Yandex.Direct
    Если интерактивную/видео: Adfox (Yandex), MyTarget (mail.ru) или NativeRoll
    Ответ написан
    Комментировать
  • По какой версии учебника Кантора по JS учиться - русской или английской?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    ИМХО, но не стоит учится по учебнику Кантора, все что научитесь - быдлокодить. Лучше Дэвида Флэнагана почитайте.

    Ну а по сабжу, у Кантора русская версия - оригинал, а английская - перевод
    Ответ написан
    3 комментария
  • Можно ли использовать (а если можно то как) vuex внутри плагина для Vue?

    bingo347
    @bingo347
    Crazy on performance...
    Тут есть несколько вариантов:

    Вариант совсем плохой: тащим Vuex за своим плагином, сами подключаем, делаем свой store - профит. Плюс только один - просто реализовать. Плохо тем, что пользователь Вашего плагина не сможет взаимодействовать с его состоянием если захочет. Так же если Ваша версия Vuex будет отличаться от версии пользователя, то у пользователя в бандле vuex окажется 2 раза.

    Вариант получше: жестко требуем у пользователя, чтоб он дал нам свой store в опциях к плагину, и инжектим в его store свой модуль. Можно так же указать vuex в peerDependencies нашего package.json
    Плюсы: используем Vuex пользователя, а не тащим свой; даем пользователю взаимодействовать с состоянием плагина.
    Минусы: засоряем store пользователя независимо от его желания; если пользователю не нужен store, он все равно будет вынужден его создать

    Хороший вариант: даем пользователю опционально возможность отдать нам свой store, а если не дал - создаем свой.
    Минус: заморочно в реализации
    Плюс: свобода действий у пользователя, из обязательных действий - только установить Vuex

    В любом случае лучше всего свое состояние держать в отдельном модуле Vuex
    Почитать про модули можно тут: https://vuex.vuejs.org/ru/guide/modules.html

    Ну и как реализовать хороший вариант, покажу на примере:
    import Vuex from 'vuex';
    import pluginStoreConfig from './store';
    
    const PLUGIN_NAME = 'MyPlugin';
    let Vue; // подключим из install
    
    // наш плагин
    export default {
      install(_Vue, options = {}) {
        Vue = _Vue;
        let {store} = options;
        if(store) {
          // если передали store - регистрируем в нем свой модуль
          store.registerModule(PLUGIN_NAME, pluginStoreConfig);
        } else {
          // не передали, для начала проверим, установлен ли Vuex в Vue
          if(!new Vue({store: {}}).$store) {
            // и если нет, установим
            Vue.use(Vuex);
          }
          // и создадим новый store с единственным модулем - нашим
          store = new Vuex.Store({modules: {
            [PLUGIN_NAME]: pluginStoreConfig
          }});
        }
        // немного упростим себе жизнь, чтоб не писать каждый раз наш нэймспейс
        // если что-то не используется, то можно убрать
        const boundStore = {
          state: store.state[PLUGIN_NAME],
          getters: store.getters[PLUGIN_NAME],
          commit(mutation, payload, options) {
            return store.commit(`${PLUGIN_NAME}/${mutation}`, payload, options);
          },
          dispatch(action, payload, options) {
            return store.dispatch(`${PLUGIN_NAME}/${action}`, payload, options);
          },
          watch(fn, cb, options) {
            return store.watch((state, getters) => fn(state[PLUGIN_NAME], getters[PLUGIN_NAME]), cb, options);
          }
        };
        // дальше творим прочую магию нашего плагина
        // ...
      }
    };


    Файл store.js будет почти обычным конфигом store, с одним исключением - работать он у нас будет в модуле, и ему нужен свой нэймспейс:
    export default {
      namespaced: true,
      state: {/* ... */},
      getters: {/* ... */},
      actions: {/* ... */},
      mutations: {/* ... */}
    };
    Ответ написан
    6 комментариев
  • Как сортировать результат по если нашли id в другой таблице?

    bingo347
    @bingo347
    Crazy on performance...
    SELECT u.* FROM users u
    INNER JOIN photos p ON p.user_id = u.id
    UNION
    SELECT u.* FROM users u
    LEFT JOIN photos p ON p.user_id = u.id
    WHERE p.id IS NULL
    Ответ написан
    Комментировать
  • Как получить случайный элемент массива без повторений при вызове функции?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    function makeGetRandomElement(initialArray) {
      var arr;
      function randomIndex() {
        return Math.floor(Math.random() * arr.length);
      }
      function reinitArray() {
        arr = initialArray.slice();
      }
      reinitArray();
      return function getRandomElement() {
        if(arr.length === 0) reinitArray();
        return arr.splice(randomIndex(), 1)[0];
      }
    }
    
    
    // использование
    var getRandomElement = makeGetRandomElement([1, 2, 3, 4, 5, 6, 7]);
    console.log(getRandomElement());
    console.log(getRandomElement());
    console.log(getRandomElement());
    console.log(getRandomElement());
    console.log(getRandomElement());
    Ответ написан
    Комментировать
  • Как применить условный оператор if к Date()?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    var clock = new Date();
    var hours = clock.getHours();
    var minute = clock.getMinutes();
    if(hours === 0 && minute === 0){
        
    };
    Ответ написан