Просмотр полной версии : Скролл дива при перетаскивании в нем элементов
sashgera
13.10.2023, 11:27
Здравствуйте
Есть див с id "dragContainer", в котором динамически создается список li. Список можно перетаскивать мышью.
При перетаскивании элемента li вверх/вниз, нужно начать скроллить див, если li перемещен за пределы высоты дива.
На данный момент скролл работает медленнее, чем перетаскивается элемент.
Пожалуйста, помогите.
JS выполняется не в браузере, а в гаджете Windows. Вот видео - https://youtube.com/shorts/P1FI2xN2Trk
var Drag = {
obj : null,
init : function(obj){
obj.onmousedown = Drag.start;
obj.style.pixelTop = 0;
obj.onDragStart = new Function();
obj.onDragEnd = new Function();
obj.onDrag = new Function();
},
start : function(e){
Drag.obj = this;
e = Drag.fixE(e);
Drag.obj.lastMouseY = e.clientY;
document.onmousemove = Drag.drag;
document.onmouseup = Drag.end;
return false;
},
drag : function(e){
e = Drag.fixE(e);
var ey = e.clientY;
var y = parseInt(Drag.obj.style.pixelTop);
var ny = parseInt(y + ey - Drag.obj.lastMouseY);
Drag.obj.style.pixelTop = ny;
Drag.obj.style.pixelLeft = 15;
Drag.obj.lastMouseY = ey;
Drag.obj.onDrag(ny, Drag.obj);
// скролл------------------------------------------------------------------------------------------
dragContainerHeight = document.getElementById("dragContainer").offsetHeight;
if (dragContainerHeight < Drag.obj.lastMouseY){
document.getElementById("dragContainer").scrollTop = Drag.obj.lastMouseY - dragContainerHeight;
}
// ------------------------------------------------------------------------------------------------
return false;
},
end : function(){
document.onmousemove = null;
document.onmouseup = null;
Drag.obj.onDragEnd(Drag.obj);
Drag.obj = null;
},
fixE : function(e){
if (typeof e == 'undefined') e = window.event;
return e;
}
};
На данный момент скролл работает медленнее, чем перетаскивается элемент.
Скролл работает с той скоростью, с которой может.
Просто надо поменять логику скролла.
Скролить окно надо не в том случае, когда мышь двигается, а когда нижняя граница перетаскиваемого элемента достигла нижней границы элемента в котором производится скролл, независимо от того, движется мышь или нет. Главное, что бы кнопка мыши была нажата.
Оставить курсор мыши в пределах окна вы все равно не сможете. Это общесистемный ресурс и браузеру он не подчиняется. Если мышь двигается, то будет двигаться и курсор.
sashgera
15.10.2023, 01:53
Скролить окно надо не в том случае, когда мышь двигается, а когда нижняя граница перетаскиваемого элемента достигла нижней границы элемента в котором производится скролл
voraa, начал делать, но возникли проблемы, которые не могу решить. Не поможете?
- если полоса прокрутки равна 0, все хорошо - скролл начинается когда перетаскиваемый элемент достиг нижней границы дива
- если полоса прокрутки больше нуля, проблема - при начале перетаскивания элемента, полоса прокрутки из начального положения уменьшается на растояние, которое равно: от текущего положения перетаскиваемого элемента до нижней границы дива
- если перетаскивать снизу вверх - скролл начинается сразу, а не когда элемент достигает верхней части дива
// переменная dragContainer - див, в котором находятся элементы
// переменная myElem - перетаскиваемый элемент
if (myElem.offsetTop > (dragContainer.offsetHeight + dragContainer.offsetTop)){
dragContainer.scrollTop = (myElem.offsetHeight + myElem.offsetTop) - (dragContainer.offsetHeight + dragContainer.offsetTop);
}
Нет. Не помогу.
Нужен весь код, что бы разбираться, что там происходит и иметь возможность тестировать.
Но я смутно представляю, что такое "гаджет" в виндовс 7, какой там js, да и 7 у меня нет.
А почему не использовать обычный нативный drag n drp?
Там проблем со скроллингом нет - все делается автоматически.
Хоть и не полностью он поддерживается даже в старых IE
sashgera
16.10.2023, 11:27
voraa, я уже пробовал что-то типа этого - https://stackoverflow.com/questions/44415228/list-sorting-with-html5-dragndrop-drop-above-or-below-depending-on-mouse но ничего не получилось, для работы в старых ie менял метод addEventListener на attachEvent
sashgera,
Подключи jquery просто, и плагин какой-нибудь, например, есть jquery-ui, там есть sortable (https://jqueryui.com/sortable/). Все версии можешь скачать здесь: jquery (https://releases.jquery.com/jquery/), jquery-ui (https://releases.jquery.com/ui/). Начинай с jquery 1.12.4 и jquery-ui 1.12.1, если что-то не работает понижай версию. Иногда можно по годам что-то подгонять, например, windows 7 вышла в 2009-м, значит jquery близкого года выпуска точно должна поддерживаться, год выпуска указан в uncompressed версиях, ну это так, windows 7 здесь просто для примера, в целом это всего касается, на будущее тебе совет просто, а поддерживаться на самом деле могут и более позднии версии.
sashgera
16.10.2023, 23:47
Rise, первое, что я пытался сделать, это подключить jquery. Но при подключении гаджет перестает работать
Но при подключении гаджет перестает работать
У вас там $ используется для каких то других целей.
Используйте jQuery.noConflict()
https://api.jquery.com/jquery.noconflict/
sashgera
18.10.2023, 13:22
Скролл при перетаскивании элементов сделал. Скажите, при скролле, расстояние между перетаскиваемым элементом и курсором увеличивается - это нормальное состояние? так и должно быть? Вот видео https://youtube.com/shorts/VbGXOzoyZ_0
Во вложении файл js с функциями drag, событие скролла отметил комментом
Ну вообще то скролл должен идти и без движения мыши, когда элемент находится в самом низу или самом верху
Вот посмотрите пример, подведите элемент просто к самому низу, и остановите мышь так, что бы нижняя рамка элемента совпадала с низом окна. Мышь не движется, а скрол идет
<head>
<style>
body {
/* Prevent the user selecting text in the example */
user-select: none;
}
#draggable {
text-align: center;
background: white;
}
.dropzone {
width: 200px;
height: 20px;
background: blueviolet;
margin: 30px 10px;
padding: 10px;
}
.dropzone.dragover {
background-color: purple;
}
.dragging {
opacity: 0.5;
}</style>
</head>
<body>
<div class="dropzone">
<div id="draggable" draggable="true">This div is draggable</div>
</div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<script>
let dragged;
/* events fired on the draggable target */
const source = document.getElementById("draggable");
source.addEventListener("drag", (event) => {
console.log("dragging");
});
source.addEventListener("dragstart", (event) => {
// store a ref. on the dragged elem
dragged = event.target;
// make it half transparent
event.target.classList.add("dragging");
});
source.addEventListener("dragend", (event) => {
// reset the transparency
event.target.classList.remove("dragging");
});
/* events fired on the drop targets */
const targets = document.querySelectorAll(".dropzone");
targets.forEach(target => {
target.addEventListener(
"dragover",
(event) => {
// prevent default to allow drop
event.preventDefault();
},
false,
);
target.addEventListener("dragenter", (event) => {
// highlight potential drop target when the draggable element enters it
if (event.target.classList.contains("dropzone")) {
event.target.classList.add("dragover");
}
});
target.addEventListener("dragleave", (event) => {
// reset background of potential drop target when the draggable element leaves it
if (event.target.classList.contains("dropzone")) {
event.target.classList.remove("dragover");
}
});
target.addEventListener("drop", (event) => {
// prevent default action (open as link for some elements)
event.preventDefault();
// move dragged element to the selected drop target
if (event.target.classList.contains("dropzone")) {
event.target.classList.remove("dragover");
event.target.appendChild(dragged);
}
});
});
</script>
</body>
sashgera
19.10.2023, 17:57
voraa, спасибо, так и сделал - https://youtu.be/sKDEyI6os-8
vBulletin® v3.6.7, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot