Я пытаюсь смоделировать действие перетаскивания в сортируемый список HTML, созданный с использованием библиотеки Sortable JS (https://github.com/SortableJS/Sortable). Он использует собственный HTML5 API для реализации перетаскиваемых элементов и сортировки в списке.
Для имитации этих событий перетаскивания я нашел и изменил следующий код JavaScript:
var triggerSortableDragAndDrop = function (selectorDrag, selectorDrop, callback) {
var DELAY_INTERVAL_MS = 10;
var MAX_TRIES = 2;
// fetch target elements
var elemDrag = document.querySelector(selectorDrag);
var elemDrop = document.querySelector(selectorDrop);
elemDrag.setAttribute('draggable',"true");
elemDrop.setAttribute('draggable',"true");
elemDrag.href="#";
var dragItems = document.querySelectorAll('[draggable=true]');
if (!elemDrag || !elemDrop) {
console.log("can't get elements");
return false;
}
var startingDropRect = elemDrop.getBoundingClientRect();
function rectsEqual(r1, r2) {
return r1.top === r2.top && r1.right === r2.right && r1.bottom === r2.bottom && r1.left === r2.left;
}
// function for triggering mouse events
function fireMouseEvent(type, elem) {
var evt = document.createEvent('MouseEvent');
evt.initMouseEvent(type, true, true, window, 1, 1, 1, 0, 0, false, false, false, false, 0, elem);
elem.dispatchEvent(evt);
};
// trigger dragging process on top of drop target
// We sometimes need to do this multiple times due to the vagaries of
// how Sortable manages the list re-arrangement
var counter = 0;
function dragover() {
counter++;
console.log('DRAGOVER #' + counter);
var currentDropRect = elemDrop.getBoundingClientRect();
if (rectsEqual(startingDropRect, currentDropRect) && counter < MAX_TRIES) {
if (counter != 1) console.log("drop target rect hasn't changed, trying again");
// mouseover / mouseout etc events not necessary
// dragenter / dragleave events not necessary either
fireMouseEvent('dragover', elemDrop);
setTimeout(dragover, DELAY_INTERVAL_MS);
} else {
if (rectsEqual(startingDropRect, currentDropRect)) {
console.log("wasn't able to budge drop target after " + MAX_TRIES + " tries, aborting");
fireMouseEvent('drop', elemDrop);
if (callback) callback(false);
} else {
setTimeout(drop, DELAY_INTERVAL_MS);
}
}
}
function drop() {
console.log('DROP');
// release dragged element on top of drop target
fireMouseEvent('drop', elemDrop);
fireMouseEvent('mouseup', elemDrop); // not strictly necessary but I like the symmetry
if (callback) callback(true);
}
// start dragging process
console.log('DRAGSTART');
fireMouseEvent('mousedown', elemDrag);
console.log('mousedown triggered');
fireMouseEvent('dragstart', elemDrag);
console.log('dragstart triggered');
// after a delay, do the first dragover; this will run up to MAX_TRIES times
// (with a delay between each run) and finally run drop() with a delay:
setTimeout(dragover, DELAY_INTERVAL_MS);
return true;
};
И разметка раздела, который я пытаюсь перетащить с помощью, выглядит следующим образом:
Когда я пытался установить точки останова при перетаскивании браузера Прослушиватели событий и выполнить вспомогательную функцию в консоли браузера с помощью:
triggerSortableDragAndDrop('#bookmarkItems > li:nth-child(2)', '#bookmarkItems > li:nth-child(2)');
Я заметил, что событие dragstart никогда не записывалось, но события mousedown и dragover были.
Как я могу получить огонь события dragstart, чтобы вызвать его слушателя? Потому что я думаю, что именно поэтому симуляция перетаскивания не работает.