меню

Раннее в JavaScript, когда почти для всего нужна была специальная функция, потому что браузеры реализовывали по своему не только новые, но и базовые функции, такие как addEventListener и attachEvent. Времена изменились, но есть несколько функций, которые каждый разработчик должен иметь в своем арсенале, чтобы повысить производительность работы.

debounce

Функция debounce крайне полезна, когда дело доходит до производительности обработчиков событий. Если вы не используете функцию debounce с событиями scroll, resize, key*, вы, вероятно, не правы. Вот функция debounce, которая сделает ваш код более эффективным:

    
  // Returns a function, that, as long as it continues to be invoked, will not
  // be triggered. The function will be called after it stops being called for
  // N milliseconds. If `immediate` is passed, trigger the function on the
  // leading edge, instead of the trailing.
 function debounce(func, wait, immediate) {
    var timeout;
    return function() {
     var context = this, args = arguments;
     var later = function() {
        timeout = null;
       if (!immediate) func.apply(context, args);
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(context, args);
   };
  };

  // Usage
  var myEfficientFn = debounce(function() {
   // All the taxing stuff you do
  }, 250);
  window.addEventListener('resize', myEfficientFn);
   
 

Функция debounce не позволяет обработчику события выполниться более одного раза в заданный промежуток времени. Это особенно выжно для часто срабатывающих событий.

poll

Иногда у вас не будет возможности отследить событие наступления желаемого состояния — если события не существует, необходимо периодически проверять определенное состояние:

   
  function poll(fn, callback, errback, timeout, interval) {
     var endTime = Number(new Date()) + (timeout || 2000);
     interval = interval || 100;

     (function p() {
             // If the condition is met, we're done! 
             if(fn()) {
                  callback();
             }
             // If the condition isn't met but the timeout hasn't elapsed, go again
              else if (Number(new Date()) < endTime) {
                 setTimeout(p, interval);
              }
             // Didn't match and too much time, reject!
             else {
                  errback(new Error('timed out for ' + fn + ': ' + arguments));
             }
     })();
 }

 // Usage:  ensure element is visible
  poll(
     function() {
          return document.getElementById('lightbox').offsetWidth > 0;
      },
      function() {
          // Done, success callback
     },
      function() {
          // Error, failure callback
      }
 );
    
 

Такой подход периодического опрашивания уже давно используется в веб и будет использоваться в будущем!

once

Иногда необходимо, чтобы какая-то функция выполнилась только однажды, подобно событию onload. Код ниже позволит вам добавить такую функциональность:

   
  function once(fn, context) { 
   var result;

   return function() { 
      if(fn) {
        result = fn.apply(context || this, arguments);
        fn = null;
      }

     return result;
    };
  }

 // Usage
  var canOnlyFireOnce = once(function() {
   console.log('Fired!');
  });

 canOnlyFireOnce(); // "Fired!"
  canOnlyFireOnce(); // nada
    
 

Функция once гарантирует, что функция будет вызвана только один раз, тем самым позволяет избежать повторной инициализации!

getAbsoluteUrl

Получение абсолютного URL из строки не такая простая задача, какой кажется. Существует конструктор URL, который не работает, если не передать ему требуемые параметры (которые иногда невозможно передать). Вот хороший трюк для получения абсолютного URL из строки:

    
  var getAbsoluteUrl = (function() {
    var a;

    return function(url) {
      if(!a) a = document.createElement('a');
     a.href = url;

     return a.href;
    };
  })();

 // Usage
  getAbsoluteUrl('/something'); // http://proweb63.ru/something
   
 

Обработка атрибута href элемента предоставляет надежный способ получения абсолютного URL.

isNative

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

    
  ;(function() {

    // Used to resolve the internal `` of values
   var toString = Object.prototype.toString;
   
    // Used to resolve the decompiled source of functions
   var fnToString = Function.prototype.toString;
   
    // Used to detect host constructors (Safari > 4; really typed array specific)
    var reHostCtor = /^\[object .+?Constructor\]$/;

   // Compile a regexp using a common native method as a template.
   // We chose `Object#toString` because there's a good chance it is not being mucked with.
   var reNative = RegExp('^' +
     // Coerce `Object#toString` to a string
     String(toString)
      // Escape any special regexp characters
     .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&')
     // Replace mentions of `toString` with `.*?` to keep the template generic.
      // Replace thing like `for ...` to support environments like Rhino which add extra info
     // such as method arity.
      .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
   );
    
    function isNative(value) {
      var type = typeof value;
      return type == 'function'
       // Use `Function#toString` to bypass the value's own `toString` method
       // and avoid being faked out.
       ? reNative.test(fnToString.call(value))
       // Fallback to a host object check because some environments will represent
       // things like typed arrays as DOM methods which may not conform to the
       // normal native pattern.
       : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
    }
   
    // export however you want
    module.exports = isNative;
  }());

 // Usage
  isNative(alert); // true
  isNative(myCustomFunction); // false
    
 

Эта функция выглядит не симпатично, но выполняет свою работу!

insertRule

Все мы знаем, что можно получить список элементов DOM по селектору (с помощью document.querySelectorAll) и для каждого из них добавить атрибут style, но более эффективным будет задать стиль для селектора (как это делается в CSS):

   
  var sheet = (function() {
   // Create the <style> tag
   var style = document.createElement('style');

    // Add a media (and/or media query) here if you'd like!
    // style.setAttribute('media', 'screen')
    // style.setAttribute('media', 'only screen and (max-width : 1024px)')

    // WebKit hack :(
   style.appendChild(document.createTextNode(''));

   // Add the <style> element to the page
    document.head.appendChild(style);

   return style.sheet;
 })();

 // Usage
  sheet.insertRule("header { float: left; opacity: 0.8; }", 1);
   
 

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

matchesSelector

Мы часто валидируем пользовательский ввод, проверяем, что все поля формы заполнены корректно, прежде, чем двигаться дальше. Но как часть мы проверяем элемент? Вы можете использовать функцию ниже для проверки, удовлетворяет ли элемент заданному селектору:

    
  function matchesSelector(el, selector) {
    var p = Element.prototype;
    var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
      return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
    };
    return f.call(el, selector);
  }

 // Usage
  matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')
    
 

Мы привели семь JavaScript-функций, которые каждый разработчик должен иметь в своем арсенале. Есть функции, которые я пропустил? Пожалуйста, поделитесь!


Возможно, вам будет интересно

Чистый код на JavaScript, 5 рекомендаций которые улучшат Ваш код.

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

Выделяем текущий пункт меню отдельным стилем на jQuery

Допустим нужно выделить текущий пункт меню отдельным стилем. Иногда, это сделать просто невозможно (в случае Ajax) или сложно из-за структуры меню и тут нам на помощь приходит JavaScript, а точнее jQuery

Понимание синхронного и асинхронного JavaScript с Async/Await

В этой статье вы узнаете о том, что такое синхронное и асинхронное программирование в JavaScript и как применяя эти знания, работать с Async/Await

JavaScript and JQuery 1.8.3 решение проблемы с функцией attr() на примере генератора пароля

Совсем недавно решил написать генератор пароля с возможностью просмотра генерированного пароля под звездочками. Для работы выбрал JQuery 1.8.3 и нативный JavaScript. При написании самого скрипта столкнулся с проблемой в JQuery 1.8.3 с функцией attr().

Оформление заявки

Документы на создание сайта

Изучите наше коммерческое предложение, заполните БРИФ и отправьте его на почту maxidebox@list.ru. Изучив все пожелания из БРИФ-а, обратным ответом оповестим Вас по стоимости разработке, ответим на вопросы.

КП на создание сайта Коммерческое предложение на созданеи сайта

Мы берем на себя ответственность за все стадии работы и полностью избавляем клиентов от забот и необходимости вникать в тонкости.

Скачать БРИФ (акета) на создание сайта Скачать БРИФ (акета) на создание сайта

Зополните у БРИФ-а все необходимые поля. Сделайте краткое описание к каждому из пунктов анкеты, привидите примеры в соответсвующий пунктах - это позволит лучше понять Ваши ожидания и требования к сайту