Javascript Helper Functions

Дата публикации 04.08.2018

 

Несколько вспомогательных функций.

 

Полифил для ИЕ, добавляющий метод closest:

// IE Polyfill  Element.closest()
if (!Element.prototype.matches) {
    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
}
if (!Element.prototype.closest) {
    Element.prototype.closest = function(s) {
        var el = this;
        if (!document.documentElement.contains(el)) return null;
        do {
            if (el.matches(s)) return el;
            el = el.parentElement || el.parentNode;
        } while (el !== null && el.nodeType === 1); 
        return null;
    }
}

 

Полифил, добавляющий метод forEach для NodeList в ИЕ:

// IE Polyfill forEach for NodeList
if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) {
    // Yes, there's really no need for `Object.defineProperty` here
    NodeList.prototype.forEach = Array.prototype.forEach;
}

 

Эмуляция метода children для ИЕ

(function (constructor) {
    if (constructor &&
        constructor.prototype &&
        constructor.prototype.children == null) {

        Object.defineProperty(constructor.prototype, 'children', {
            get: function () {
                var i = 0, node, nodes = this.childNodes, children = [];
                //iterate all childNodes
                while (node = nodes[i++]) {
                    //remenber those, that are Node.ELEMENT_NODE (1)
                    if (node.nodeType === 1) { children.push(node); }
                }
                return children;
            }
        });
    }
  //apply the fix to all HTMLElements (window.Element) and to SVG/XML (window.Node)
})(window.Node || window.Element);

 

Проверка, поддерживает ли браузер CSS-свойство:

let SupportsCSS = function (property, value) {
	try {
		let element = document.createElement('span');
		if (element.style[property] !== undefined) 	element.style[property] = value; 
		else return false;

		return element.style[property] === value;
	} catch (e) {
		return false;
	}
};

 

Проверка, поддерживается ли элемент picture:

let isSupportPicture = false;

isSupportPicture = (function () {
	try {
		let element = document.createElement('img');
		element.setAttribute('srcset', 'test');
		
		return element.srcset === 'test';
	} catch (e) {
		return false;
	}   
})();

 

Проверить, поддерживает ли браузер web-worker:

if (!!window.Worker) {
	console.log('worker');
}

 

Проверка мобильного устройства по User-agent:

let isMobile = false;
if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)) isMobile = true;

 

Добавить события для тачскрина:

window.addEventListener('DOMContentLoaded',function() {	
	['touchstart','touchmove','touchend','touchcancel','gesturestart','gesturechange','gestureend','orientationchange'].forEach(function(ev) {
		document.body.addEventListener(ev,function(e) {
		});
	});
});

 

Поиск границы массива, в которую попадает значение:

function reduce(search, pattern) {
    let cnt = pattern.length;
    for (i = 0; i < cnt; i++) {
        if ((typeof(pattern[i + 1]) == 'undefined') || (search >= pattern[i] && search < pattern[i + 1]) ) {
            return i;
        }
    }
}

//example:
let array = [0,320,380,480,600,800,1000];
reduce(390, array);

Например, переданное в функцию число 390 вернет индекс 2 (больше 380, но меньше 480).

 

Форматирование цены:

/**
 * Number.prototype.format(n, x, s, c)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of whole part
 * @param mixed   s: sections delimiter
 * @param mixed   c: decimal delimiter
 */
Number.prototype.format = function(n, x, s, c) {
    let re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
        num = this.toFixed(Math.max(0, ~~n));

    return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};

//example:
parseFloat(1258000).format(2, 3, ' ', ',');
//will be output  1 258 000,00

 

Событие domReady как Promise. Позволяет использовать Promise.all:

document.ready = new Promise((resolve) => document.addEventListener('DOMContentLoaded', resolve));

document.ready.then(() => {	
	//do something
});
	
Promise.all([document.ready, otherPromise]).then((data) => {
	//do other	
});