// Dynamic Adapt v.1 // HTML data-da="where(uniq class name),when(breakpoint),position(digi)" // e.x. data-da=".item,992,2" // Andrikanych Yevhen 2020 // https://www.youtube.com/c/freelancerlifestyle "use strict"; function DynamicAdapt(type) { this.type = type; } DynamicAdapt.prototype.init = function () { const _this = this; // массив объектов this.оbjects = []; this.daClassname = "_dynamic_adapt_"; // массив DOM-элементов this.nodes = document.querySelectorAll("[data-da]"); // наполнение оbjects объктами for (let i = 0; i < this.nodes.length; i++) { const node = this.nodes[i]; const data = node.dataset.da.trim(); const dataArray = data.split(","); const оbject = {}; оbject.element = node; оbject.parent = node.parentNode; оbject.destination = document.querySelector(dataArray[0].trim()); оbject.breakpoint = dataArray[1] ? dataArray[1].trim() : "767"; оbject.place = dataArray[2] ? dataArray[2].trim() : "last"; оbject.index = this.indexInParent(оbject.parent, оbject.element); this.оbjects.push(оbject); } this.arraySort(this.оbjects); // массив уникальных медиа-запросов this.mediaQueries = Array.prototype.map.call(this.оbjects, function (item) { return '(' + this.type + "-width: " + item.breakpoint + "px)," + item.breakpoint; }, this); this.mediaQueries = Array.prototype.filter.call(this.mediaQueries, function (item, index, self) { return Array.prototype.indexOf.call(self, item) === index; }); // навешивание слушателя на медиа-запрос // и вызов обработчика при первом запуске for (let i = 0; i < this.mediaQueries.length; i++) { const media = this.mediaQueries[i]; const mediaSplit = String.prototype.split.call(media, ','); const matchMedia = window.matchMedia(mediaSplit[0]); const mediaBreakpoint = mediaSplit[1]; // массив объектов с подходящим брейкпоинтом const оbjectsFilter = Array.prototype.filter.call(this.оbjects, function (item) { return item.breakpoint === mediaBreakpoint; }); matchMedia.addListener(function () { _this.mediaHandler(matchMedia, оbjectsFilter); }); this.mediaHandler(matchMedia, оbjectsFilter); } }; DynamicAdapt.prototype.mediaHandler = function (matchMedia, оbjects) { if (matchMedia.matches) { for (let i = 0; i < оbjects.length; i++) { const оbject = оbjects[i]; оbject.index = this.indexInParent(оbject.parent, оbject.element); this.moveTo(оbject.place, оbject.element, оbject.destination); } } else { //for (let i = 0; i < оbjects.length; i++) { for (let i = оbjects.length - 1; i >= 0; i--) { const оbject = оbjects[i]; if (оbject.element.classList.contains(this.daClassname)) { this.moveBack(оbject.parent, оbject.element, оbject.index); } } } }; // Функция перемещения DynamicAdapt.prototype.moveTo = function (place, element, destination) { element.classList.add(this.daClassname); if (place === 'last' || place >= destination.children.length) { destination.insertAdjacentElement('beforeend', element); return; } if (place === 'first') { destination.insertAdjacentElement('afterbegin', element); return; } destination.children[place].insertAdjacentElement('beforebegin', element); } // Функция возврата DynamicAdapt.prototype.moveBack = function (parent, element, index) { element.classList.remove(this.daClassname); if (parent.children[index] !== undefined) { parent.children[index].insertAdjacentElement('beforebegin', element); } else { parent.insertAdjacentElement('beforeend', element); } } // Функция получения индекса внутри родителя DynamicAdapt.prototype.indexInParent = function (parent, element) { const array = Array.prototype.slice.call(parent.children); return Array.prototype.indexOf.call(array, element); }; // Функция сортировки массива по breakpoint и place // по возрастанию для this.type = min // по убыванию для this.type = max DynamicAdapt.prototype.arraySort = function (arr) { if (this.type === "min") { Array.prototype.sort.call(arr, function (a, b) { if (a.breakpoint === b.breakpoint) { if (a.place === b.place) { return 0; } if (a.place === "first" || b.place === "last") { return -1; } if (a.place === "last" || b.place === "first") { return 1; } return a.place - b.place; } return a.breakpoint - b.breakpoint; }); } else { Array.prototype.sort.call(arr, function (a, b) { if (a.breakpoint === b.breakpoint) { if (a.place === b.place) { return 0; } if (a.place === "first" || b.place === "last") { return 1; } if (a.place === "last" || b.place === "first") { return -1; } return b.place - a.place; } return b.breakpoint - a.breakpoint; }); return; } }; const da = new DynamicAdapt("max"); da.init();