Вот вариант; Я не могу предположить, что это так же надежно или совместимо с браузером, как jQuery, но это должно показать общую идею. Я использую переменную-дескриптор dragged
и использую пару классов для различения draggable
и draggable-child
элементов. Есть простая проверка границ для детей. Он довольно удобен для заполнения и других вещей, которые вы хотели бы принять во внимание.
let dragged;
document.addEventListener("mouseup", e => dragged = null);
document.addEventListener("mousedown", e => {
if (e.target.classList.contains("draggable-handle")) {
dragged = e.target.parentElement;
}
});
document.addEventListener("mousemove", e => {
if (dragged) {
e.preventDefault();
const x = +(dragged.style.left.match(/-?\d+/g) || 0) + e.movementX;
const y = +(dragged.style.top.match(/-?\d+/g) || 0) + e.movementY;
const w = dragged.getBoundingClientRect().width;
const h = dragged.getBoundingClientRect().height;
if (dragged.classList.contains("draggable-child")) {
const r = dragged.parentElement.getBoundingClientRect();
const pw = r.width;
const ph = r.height;
if (x < 0 || y < 0 || x + w >= pw || y + h >= ph) {
return;
}
}
dragged.style.top = `${y}px`;
dragged.style.left = `${x}px`;
}
});
#modalPar {
width: 300px;
height: 150px;
border: 1px solid black
}
#myModal {
width: 200px;
height: 100px;
border: 1px solid black
}
.draggable, .draggable-child, .draggable-handle {
position: absolute;
}
.draggable-handle {
padding: 0.3em;
background: black;
color: white;
cursor: grab;
}
<div id="modalPar" class="draggable">
<div class="draggable draggable-handle">[drag]</div>
<div id="myModal" class="draggable draggable-child">
<div class="draggable draggable-handle">[drag]</div>
</div>
</div>