Меню ×
Семь важных функций JavaScript

Семь важных функций JavaScript

Раннее в 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-функций, которые каждый разработчик должен иметь в своем арсенале. Есть функции, которые я пропустил? Пожалуйста, поделитесь!

Голосов: 904 | Просмотров: 6655

наверх