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 });