Как поменять местами блоки на странице
Почти традиционной для этого дня числовой или календарной загадки сегодня ещё не было в связи с занятостью :)
Сделаем её сейчас, заодно опубликовав полезный образец по обмену местами (свопингу) блоков на странице с помощью перетаскивания их мышью. Всё реализовано на объекте DragManager
, который становится обработчиком событий dragstart
, dragend
и функции DragContainer
, которая добавляет в менеджер последовательно переданные ей через аргумент элементы стилевого класса dragContainer
(в нашем случае класс назначается обычному списку <ul>
, а перетаскиваемые блоки будут его элементами <li>
с HTML-атрибутом draggable). Метод checkContainers
, проверяющий, достигнута ли цель перетаскивания блоков, предполагает, что нужный контент содержится в потомках элементов из массива dragContainers
(это всё те же элементы <li>
, вложенные в список <ul class="dragContainer">
). Если цель достигнута, обработку можно и прекратить, соответствующий код в исходнике закомментирован. В браузере должен быть включен JavaScript, чтобы всё работало.
Итак, перетаскивая блоки с цифрами, собери день и месяц рождения нашего дорогого Одмина, то есть, меня (кстати, а ещё хоть какую-нибудь дату ДД.ММ можно из этого собрать?):
- 5
- 2
- 0
- 3
Ещё одну дату ДДММ из этих цифр собрать можно :)
В старину, а точней, лет 10 назад, такое уже тоже можно было делать (ниже прилагается старый исходник), но телодвижений требовалось примерно вдвое больше. Применение JQuery и новых стандартов JS заметно упрощает задачу. Исходный текст старого скрипта можно увидеть в коде страницы (кодировка Юникода UTF-8).
Обмен блоков на странице средствами HTML5, старый код, открыть в текущем окне/вкладке (10 Кб)
Ниже публикуется исходник показанного в начале статьи нового примера на swap blocks (без стандартного обрамления HTML).
<style> /* основной контейнер */ .dragContainer { list-style-type: none; margin: 0 auto; text-align: center; width: 40em; padding: 1em; border: 1px solid transparent; } .dragContainer:hover { border: 1px solid #999; } /* перетаскиваемый элемент */ .dragContainer li { display: inline; border: 1px solid #ccc; margin: 0.5em; line-height: 2em; padding: 0 2em; cursor: move; } .dragContainer li:before { /* в начале */ } .dragContainer li:last-of-type { /*в конце */ margin-bottom: 0; } .dragContainer li:hover { /* поверх */ background-color: #eee; } .dragContainer li.my_drag_class { /* при размещении */ border: 1px dashed #999; background-color: #cfc; } </style> <ul class="dragContainer"> <li draggable="true">5</li> <li draggable="true">2</li> <li draggable="true">0</li> <li draggable="true">3</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> let DragManager = { dragContainers: [], currentContainer: null, add: function(dragContainer) { this.dragContainers.push(dragContainer); }, handleEvent: function(event) { if (event.type == 'dragstart') { let containers = this.dragContainers.filter(function(container) { return container.contains(event.target); }); if (containers.length > 0) { this.currentContainer = containers[0]; this.currentContainer.activate(); } } if (this.currentContainer !== null) { this.currentContainer.handleEvent(event); if (event.type == 'dragend') { this.currentContainer.deactivate(); this.currentContainer = null; } } } }; window.addEventListener('dragstart', DragManager); window.addEventListener('dragend', DragManager); function DragContainer (container) { this.element = container; this.items = $('> li', this.element); this.draggingItem = null; DragManager.add(this); } DragContainer.prototype.contains = function(target) { return $(this.element).find(target).length; } DragContainer.prototype.handleEvent = function(event) { //Связываем this с объектом DragContainer, а не с элементом, на котором было запущено событие let $t = $(event.target); if (event.type == 'dragstart') { this.draggingItem = event.target; event.dataTransfer.setData('text/html', this.draggingItem.innerHTML); } if (event.type == 'dragover' && this.draggingItem != event.target) { $t.addClass('my_drag_class'); if (event.preventDefault) { event.preventDefault(); //не выполнять действий по умолчанию! } event.dataTransfer.dropEffect = 'move'; } if (event.type == 'dragleave') { $t.removeClass('my_drag_class'); } if (event.type == 'drop' && this.draggingItem != null) { //Собственно, обмен блоков this.draggingItem.innerHTML = event.target.innerHTML; event.target.innerHTML = event.dataTransfer.getData('text/html'); } if (event.type == 'dragend' || event.type == 'drop') { this.items.removeClass('my_drag_class'); this.draggingItem = null; checkContainers(); //проверка на окончание } } DragContainer.prototype.activate = function() { for (let i = 0, j=this.items.length; i < j; i++) { this.items[i].addEventListener('dragenter', this.handleEvent.bind(this)); this.items[i].addEventListener('dragover', this.handleEvent.bind(this)); this.items[i].addEventListener('dragleave', this.handleEvent.bind(this)); this.items[i].addEventListener('drop', this.handleEvent.bind(this)); } } DragContainer.prototype.deactivate = function() { this.draggingItem = null; for (let i = 0, j=this.items.length; i < j; i++) { this.items[i].removeEventListener('dragenter', this.handleEvent); this.items[i].removeEventListener('dragover', this.handleEvent); this.items[i].removeEventListener('dragleave', this.handleEvent); this.items[i].removeEventListener('drop', this.handleEvent); } } let dragContainers = document.getElementsByClassName('dragContainer'); for(let i =0, j=dragContainers.length; i < j; i++) { new DragContainer(dragContainers[i]); } let checkContainers = function() { let s = ''; for (let i =0, j=dragContainers.length; i < j; i++) { s += $(dragContainers[i]).children().text(); } let good = (s == '2305'); for (let i =0, j=dragContainers.length; i < j; i++) { //если код правильный - подсветить $(dragContainers[i]).children().css('background-color',(good ? '#fcc' : 'transparent')); } if (good) { //Убрать комментарии, чтобы прекратить перетаскивание //window.removeEventListener('dragstart', DragManager); //window.removeEventListener('dragend', DragManager); } } </script>
23.05.2020, 21:49 [1958 просмотров]