предисловие
Сортировка списка перетаскиванием является относительно распространенным требованием в бизнесе.Обычные библиотеки перетаскивания JS включают Sortable.js, Vue.Draggable и т. д. Собственное событие перетаскивания HTML для сортировки перетаскиванием несложно в сочетании с Vue.transition-group
API перетаскивания HTML5
draggableсобственностьtrue(Текст, картинки и ссылкиdraggableПо умолчаниюtrue)
<div draggable="true">能被拖放的元素</div>
событие перетаскивания
Перетаскивание включает два элемента: один — перетаскиваемый элемент (исходный объект), а другой — элемент зоны перетаскивания (целевой объект). Как показано на рисунке ниже, удерживайте элемент A и перетащите его к элементу B. Элемент A является исходным объектом, а элемент B — целевым объектом.
Различные объекты имеют разные события перетаскивания.
| триггерный объект | название события | иллюстрировать |
|---|---|---|
| исходный объект | dragstart | Запускается, когда исходный объект начинает перетаскиваться |
| drag | Повторно срабатывает при перетаскивании исходного объекта | |
| dragend | В конце исходного объекта сопротивления | |
| цель | dragenter | Запускается, когда исходный объект начинает входить в область действия целевого объекта |
| dragover | Запускается, когда исходный объект перемещается в пределах границ целевого объекта. | |
| dragleave | Запускается, когда исходный объект покидает область действия целевого объекта. | |
| drop | Запускается, когда исходный объект освобождается в пределах области действия целевого объекта. |
нужно знать, это:
dragenterа такжеdragoverПоведение события по умолчанию заключается в отказе принять любой элемент, который был удален. Следовательно, мы должны использовать как в событиях перетаскивания, так и в событиях перетаскиванияpreventDefaultЧтобы предотвратить поведение браузера по умолчанию; и хотите стать целевым объектом, может отпустить область, вы должны установитьdragoverа такжеdrop
Перетащите и падение есть другие свойства и методы, но результаты, которые мы хотим достичь сегодня, нужно только иметь эти свойства, а методы, упомянутые выше, могут, если вы хотите включить, вы можете обратитьсяAPI перетаскивания HTML
Перетащите
Затем мы используем API перетаскивания для реализации сортировки списка перетаскиванием, а код основан на Vue.
Забудьте пока о сортировке анимаций. Код не сложный, поэтому я его весь выложил, а потом объяснил идею реализации:
- Поскольку перетаскивание происходит в реальном времени, оно не используется.
dropвместо этого используетсяdragenterТриггерная сортировка. - записать индекс исходного объекта, когда он начинает перетаскиваться
dragIndexКогда он входит в целевой объект (соответствующийdragenterСобытие), вставьте его в расположение целевого объекта. - в
dragenterВ методе есть суждениеthis.dragIndex !== index(index — это индекс текущего целевого объекта), потому чтоdragenter
Окончательный эффект показан на следующем рисунке:
<template>
<ul class="list">
<li
@dragenter="dragenter($event, index)"
@dragover="dragover($event, index)"
@dragstart="dragstart(index)"
draggable
v-for="(item, index) in list"
:key="item.label"
class="list-item"
>
{{item.label}}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
list: [
{ label: '列表1' },
{ label: '列表2' },
{ label: '列表3' },
{ label: '列表4' },
{ label: '列表5' },
{ label: '列表6' },
],
dragIndex: '',
enterIndex: '',
};
},
methods: {
dragstart(index) {
this.dragIndex = index;
},
dragenter(e, index) {
e.preventDefault();
// 避免源对象触发自身的dragenter事件
if (this.dragIndex !== index) {
const source = this.list[this.dragIndex];
this.list.splice(this.dragIndex, 1);
this.list.splice(index, 0, source);
// 排序变化后目标对象的索引变成源对象的索引
this.dragIndex = index;
}
},
dragover(e, index) {
e.preventDefault();
},
},
};
</script>
<style lang="scss" scoped>
.list {
list-style: none;
.list-item {
cursor: move;
width: 300px;
background: #EA6E59;
border-radius: 4px;
color: #FFF;
margin-bottom: 6px;
height: 50px;
line-height: 50px;
text-align: center;
}
}
</style>
Минус HTML и CSS, ядроdragenterС помощью не более 15 строк кода можно реализовать функцию сортировки методом перетаскивания. Конечно, этот эффект перетаскивания немного тупой, и ниже используется тот, который поставляется с Vue.transition-groupКомпонент, добавляющий плавные переходы в сортировку.
Сортировать анимацию
Если вы не знакомы с Vuetransition-groupПожалуйста, изучите VueСортировка перехода списков, которые здесь повторяться не будут.
Для облегчения сравнения с приведенным выше кодом, мы также выкладываем все коды одновременно, вы можете видеть, что изменения в коде невелики.ulэлемент меняется наtransition-group,существуетmethodsновое вshuffleметод добавления перехода в CSStransition: transform .3s;Сортировка может быть реализована в начале диаграммы эффекта сопротивления, показанной в первом.
вы можете нажатьэта ссылкаИметь онлайн-опыт.
<template>
<div>
<transition-group
name="drag"
class="list"
tag="ul"
>
<li
@dragenter="dragenter($event, index)"
@dragover="dragover($event, index)"
@dragstart="dragstart(index)"
draggable
v-for="(item, index) in list"
:key="item.label"
class="list-item">
{{item.label}}
</li>
</transition-group>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{ label: '列表1' },
{ label: '列表2' },
{ label: '列表3' },
{ label: '列表4' },
{ label: '列表5' },
{ label: '列表6' },
],
dragIndex: '',
enterIndex: '',
};
},
methods: {
shuffle() {
this.list = this.$shuffle(this.list);
},
dragstart(index) {
this.dragIndex = index;
},
dragenter(e, index) {
e.preventDefault();
// 避免源对象触发自身的dragenter事件
if (this.dragIndex !== index) {
const moving = this.list[this.dragIndex];
this.list.splice(this.dragIndex, 1);
this.list.splice(index, 0, moving);
// 排序变化后目标对象的索引变成源对象的索引
this.dragIndex = index;
}
},
dragover(e, index) {
e.preventDefault();
},
},
};
</script>
<style lang="scss" scoped>
.list {
list-style: none;
.drag-move {
transition: transform .3s;
}
.list-item {
cursor: move;
width: 300px;
background: #EA6E59;
border-radius: 4px;
color: #FFF;
margin-bottom: 6px;
height: 50px;
line-height: 50px;
text-align: center;
}
}
</style>
Если вы хотите использовать собственный JS для реализации сортировки перетаскиванием и анимации перехода списков, вы можете обратиться к этой статье:JS DRAG Сортировка перетаскиванием