skip to Main Content

I have a draggable div, which is a popup window, when a button gets clicked.

When I drag the div to the end of the viewport, I can drag it also out of it. So the body of the page keeps getting bigger. I want to have something like a barrier, which stops the div, when it hits it.

First of all, this is my code:

(not plain html –> jsp)

<html>
    <head>
        <link rel="stylesheet" href="/www/css/styles.css">
        <link id="favicon" rel="icon" type="image/x-icon" href="/www/images/favicon-dark-mode.png">
        <title>${title}</title>
    </head>
    <body class="${cssClass}">
        <header class="main-site-header">
            <g:navigation activeItem="${activeItem}"/>
            <div class="header-title">${title}</div>
            <ul class="navigation-buttons ul-scaling">
                <li><a href="mailto:[email protected]">Contact Us</a></li>
                <li><a target="_blank" href="https://javawebapp.onrender.com/">Other Projects</a>
                </li>
                <li><a target="_blank" href="https://www.getabstract.com/en/">Click Me</a></li>
            </ul>
        </header>
        <main>
            <div class="popup-flex">
                <div class="hidden-add-author-popup">
                    <div class="draggable"></div>
                    <h1 style="z-index: -1;">Add Author</h1>
                    <form>
                        <input type="text" class="label-text" placeholder="Firstname">
                    </form>
                    <form>
                        <input type="text" class="label-text" placeholder="Surname">
                    </form>
                    <form>
                        <input type="text" class="label-text" placeholder="Gender">
                    </form>
                    <button class="submit-button" id="cancel-button">Cancel</button>
                    <input type="submit" class="submit-button" id="submit-popup">
                </div>
            </div>
            <jsp:doBody/>
        </main>
        <script src="/www/js/scripts.js" type="text/javascript"></script>
    </body>
</html>
.draggable {
    position: absolute;
    width: 15rem;
    height: 5rem;
    cursor: move;
    z-index: 10;
}

.popup-flex {
    display: flex;
    justify-content: center;
    align-items: center;
}

.hidden-add-author-popup {
    position: absolute;
    background-color: var(--current-popup-color);
    color: var(--current-header-color);
    z-index: 9;
    margin-top: 45rem;
    display: none;
    border: solid var(--current-header-color);
    border-radius: 1rem;
    padding: 1rem;
    box-shadow: 0 0 10px 0 var(--current-text-color);
}
//--------------------------------------------------------------------
//                    POPUP AUTHOR FIELD LOGIC
//--------------------------------------------------------------------

submitButtonPopup.addEventListener('click', () => {
    addAuthorPopup.style.display = 'none';
})

addAuthorButton.addEventListener('click', () => {
    addAuthorPopup.style.display = 'block';
});

//--------------------------------------------------------------------
//                  CANCEL BUTTON ONCLICK EVENTS
//--------------------------------------------------------------------
cancelButton.addEventListener('click', () =>{
    authorFirstnameInnerText.value = '';
    authorSurnameInnerText.value = '';
    authorGenderInnerText.value = '';
    addAuthorPopup.style.display = 'none';
});

//--------------------------------------------------------------------
//                  MAKE AUTHOR POPUP DRAGGABLE
//--------------------------------------------------------------------
// Make the DIV element draggable:
dragElement(document.querySelector(".hidden-add-author-popup"));

function dragElement(elmnt) {
    var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    if (document.querySelector(".draggable")) {
        // if present, the header is where you move the DIV from:
        document.querySelector(".draggable").onmousedown = dragMouseDown;
    } else {
        // otherwise, move the DIV from anywhere inside the DIV:
        elmnt.onmousedown = dragMouseDown;
    }

    function dragMouseDown(e) {
        e.preventDefault();
        // get the mouse cursor position at startup:
        document.onmouseup = closeDragElement;
        // call a function whenever the cursor moves:
        document.onmousemove = elementDrag;
    }

    function elementDrag(e) {
        e.preventDefault();
        // calculate the new cursor position:
        // set the element's new position:
        if (e.clientY === 1003 || e.clientY > 1003) {
            moveDown = false;
        }
        if(moveDown) {
            elmnt.style.top = e.clientY - 743 + "px";
        }
        elmnt.style.left = e.clientX - 139 + "px";
        console.log('x: ' + e.clientX);
        console.log('Y: ' + e.clientY);
    }

    function closeDragElement() {
        // stop moving when mouse button is released:
        document.onmouseup = null;
        document.onmousemove = null;
    }
}

I’ve tried to track the position of the cursor, and when it reaches 1003 or below, the draggable object should stop. That’s not a good way to solve this problem, because there are different screen sizes. So 1003 would be inappropriate with other screens.

Thank you for responding!

2

Answers


  1. Chosen as BEST ANSWER

    Answer to my own question:

    I can get the availabel screen size with the properties

    window.innerWidth and window.innerHeight.

    In combination with getBoundingClientRect, I've got the distance from the div to the end of the viewports. When the div hits for example the left edge of the viewport, the left property is going to be added by 0.1px. It looks a little weird, but I'm fine with that for now.

    Here is the code:

    //--------------------------------------------------------------------
    //                  MAKE AUTHOR POPUP DRAGGABLE
    //--------------------------------------------------------------------
    // Make the DIV element draggable:
    dragElement(document.querySelector(".hidden-add-author-popup"));
    
    function dragElement(elmnt) {
        var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        if (document.querySelector(".draggable")) {
            // if present, the header is where you move the DIV from:
            document.querySelector(".draggable").onmousedown = dragMouseDown;
        } else {
            // otherwise, move the DIV from anywhere inside the DIV:
            elmnt.onmousedown = dragMouseDown;
        }
    
        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            // get the mouse cursor position at startup:
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            // call a function whenever the cursor moves:
            document.onmousemove = elementDrag;
        }
    
        function elementDrag(e) {
            const popupBoundingClientRect = elmnt.getBoundingClientRect();
            const popupLeft = popupBoundingClientRect.left;
            const popupRight = popupBoundingClientRect.right;
            const popupTop = popupBoundingClientRect.top;
            const popupBottom = popupBoundingClientRect.bottom;
            const popupWidth = popupBoundingClientRect.width;
            const popupHeight = popupBoundingClientRect.height;
            if(popupLeft <= 0) {
                elmnt.style.left = "0.1px";
            }
            else if(window.innerWidth <= popupRight) {
                elmnt.style.left = `${window.innerWidth - popupWidth - 0.1}px`;
            }
            else {
                //IF POPUP WINDOW IS WITHIN DEFAULT VIEWPORT [ONLY X-AXIS]
                e = e || window.event;
                e.preventDefault();
                // calculate the new cursor position:
                pos1 = pos3 - e.clientX;
                pos2 = pos4 - e.clientY;
                pos3 = e.clientX;
                pos4 = e.clientY;
                // set the element's new position:
                elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
                elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
            }
            if(popupTop <= 0) {
                elmnt.style.top = "0.1px";
            }
            else if(window.innerHeight <= popupBottom) {
                elmnt.style.top = `${window.innerHeight - popupHeight - 0.1}px`;
            }
            else {
                //IF POPUP WINDOW IS WITHIN DEFAULT VIEWPORT [ONLY X-AXIS]
                e = e || window.event;
                e.preventDefault();
                // calculate the new cursor position:
                pos1 = pos3 - e.clientX;
                pos2 = pos4 - e.clientY;
                pos3 = e.clientX;
                pos4 = e.clientY;
                // set the element's new position:
                elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
                elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
            }
        }
    
        function closeDragElement() {
            // stop moving when mouse button is released:
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    I hope this helps, comment if not.


  2. To stop a draggable div at the viewport’s edge, you’ll want to monitor its position during the drag event. Use javascript to check the div’s coordinates relative to the viewport. If the div’s position is about to exceed the viewport dimensions, stop updating its position. This keeps the div within visible bounds. React, Vue, or just plain javascript can handle this by adding conditional checks in your drag logic. No code example here, but the logic is about comparing the div’s position against window.innerWidth and window.innerHeight to create the barrier effect you’re looking for.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search