Таким образом, это будет соответствовать категории ответов «вам нужно подойти под другим углом».
Избегайте - насколько это возможно - манипулируйте DOM с event.target/event.currentTarget в ваших подключенных обработчиках.
Пара вещей по-разному:
Ваш ondragleave
и ondragenter
обработчики должны просто установить некоторые соответствующие «состояние» атрибуты в контроллере/ViewModel/магазины
Когда обработчик будет решена, это вообще запускает перерисовку в Мифриле. Внутренне m.startComputation()
начинается, ваш обработчик называется, затем m.endComputation()
Ваша «функция просмотра» снова запускается. Затем он отражает измененные модели. Ваши действия не меняют представления, ваши взгляды вызывают действия, которые влияют на модели, а затем реагируют на эти изменения. MVC, не MVVM
Модель
В контроллере, создать модель, которая отслеживает все состояния, Вы должны показать свое перетаскивание UI
ctrl.dragging = m.prop(null)
ctrl.groups = m.prop([
{
name: 'Group A',
dragOver: false,
items: ['Draggable One', 'Draggable Two']
},
...
// same structure for all groups
])
Вид
На ваш взгляд, настройте пользовательский интерфейс, который отражает состояние ваших моделей.Есть обработчики событий, которые проходят достаточную информацию о действиях к достаточно контроллер-, что он может надлежащим образом реагировать на действия манипулируют модель соответственно
return ctrl.groups.map(function (group, groupIdx) {
return m('.group',[
m('.header', group.name),
m('ul',
{
style: { background: (group.dragOver ? 'blue' : '')},
ondragleave: function() {ctrl.handleDragLeave(groupIdx)},
ondragenter: function() {ctrl.handleDragEnter(groupIdx)},
ondrop: function() {ctrl.handleDrop(groupIdx)},
ondragover: function (e) {e.preventDefault()}
},
group.items.map(function (item, itemIdx) {
return m('li',
{
draggable: true,
ondragstart: function() {ctrl.handleDragStart(itemIdx, groupIdx)}
},
item
})
)
])
})
Теперь его настроить таким образом, что группа может правильно отображаться, реагируя на изменения состояния/модели вашего контроллера. Нам не нужно манипулировать dom, чтобы сказать, что группа имеет новый элемент, группе нужен новый цвет фона или что-то еще. Нам просто нужно подключить обработчики событий, чтобы контроллер мог манипулировать вашей моделью, а затем представление будет перерисовываться на основе этой модели.
Контроллер
Ваш контроллер поэтому может иметь обработчик, которые имеют всю информацию от действий, необходимых для обновления модели.
Вот что некоторые обработчики на контроллере будет выглядеть следующим образом:
ctrl.handleDragStart = function (itemIdx, groupIdx) {
ctrl.dragging({itemIdx: itemIdx, groupIdx: groupIdx})
}
ctrl.handleDragEnter = function (groupIdx) {
ctrl.groups()[groupIdx].dragOver = true
}
ctrl.handleDragLeave = function (groupIdx) {
ctrl.groups()[groupIdx].dragOver = false
}
ctrl.handleDrop = function (toGroupIdx) {
var groupIdx = ctrl.dragging().groupIdx
var itemIdx = ctrl.dragging().itemIdx
var dropped = ctrl.groups()[groupIdx].items.splice(itemIdx, 1)[0]
ctrl.groups()[toGroupIdx].items.push(dropped)
ctrl.groups()[toGroupIdx].dragOver = false
ctrl.dragging(null)
}
Попробуйте придерживаться обработчиков событий MVC модель MITHRIL призывают действия на контроллере, который манипулирует модели. Затем представление реагирует на изменения этих моделей. Это обходит необходимость запутываться со спецификой событий DOM.
Вот полный пример JSbin показывая, что вы пытаетесь добраться до:
https://jsbin.com/pabehuj/edit?js,console,output
я получить желаемый эффект, не беспокоясь о делегировании событий на всех.
Кроме того, обратите внимание, что в JSbin, в ondragenter
обработчик:
ondragenter: function() {
if (ctrl.dragging().groupIdx !== groupIdx) {
ctrl.handleDragEnter(groupIdx)
}
}
Это так Droppable область не меняет цвет на свой собственный перетаскиваемым, что одна из вещей, которые я думаю, вы в вашем ответе.
Где вы прикрепляли эти обработчики? –