Search code examples
javascriptdraggablemoveable

draggable div but only moved by header? javascript only


i've got my draggable element etc but i want to make it only moveable by the header so you can still highlight/click on things within the div. i can only use javascript :) i got this piece of code from W3Schools but i don't know much about editing/writing javascript :,D

thank u !! (ps, i have the css sorted out but in my code everything is jumbled and i cannot be bothered to copy and paste it so it makes sense - but if it's needed then i'll happily provide!!)

dragElement(document.getElementById("elem"));

function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.id + "header")) {
    /* if present, the header is where you move the DIV from:*/
    document.getElementById(elmnt.id + "header").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) {
    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;
  }
}


<div id="elem" onmousedown='mydragg.startMoving(this,"container",event);' onmouseup='mydragg.stopMoving("container");' style="width: 185px;height: 117px; display:none; z-index:11">
    <div class="elemTitle">
    play some music?
    <button style="text-align:right; float:right;" onClick="closePopup()"> x </button>
    </div>
    <div id="musicplayer">
        <div>
            <marquee scrollamount="8" class="songtitle"></marquee>
        </div>
 
        <table class="controls">
            <tr>
                <td>
                    <div class="prev-track" onclick="prevTrack()"><i class="fas fa-backward"></i></div>
                </td>
                <td>
                    <div class="playpause-track" onclick="playpauseTrack()" ><i class="fas fa-play"></i></div>
                </td>
                <td>
                    <div class="next-track" onclick="nextTrack()"><i class="fas fa-forward"></i></div>
                </td>
            </tr>
        </table>
 
        <div class="seeking">
            <div class="current-time">00:00</div>
 
            <input type="range" min="1" max="100" value="0" class="seek_slider" onchange="seekTo()">
 
            <div class="total-duration">0:00</div>
        </div>
 
        <audio id="music" src=""></audio> 
    </div>



Solution

  • I'm not sure what exactly needed to be changed to make it work, but position: absolute is necessary on the element to be dragged (at least after the dragging starts).

    It's also now set up so that the title can be passed as a handle and used to move the div around, and added conditions for if the element is dropped while position is < 0 at top or left. Could use conditions for right and bottom being > width or height, and a event handler for onmouseout to drop the dragged element would not be a bad idea as the element is held onto otherwise.

    The event listeners should also be removed when not needed rather than just nulled away, as that can cause a memory leak as they are still attached so are still available to the running code.

    This tutorial is meant for a draggable and resizable element, but you could adapt it to just make the element draggable. Surely there are other guides out there too. Highly recommend MDN - Mozilla Developer Network - the documentation is detailed, and the examples are generally high quality and concentrate on learning the parts of a larger thing well rather than just learning the basics of the thing as W3Schools tends to do.


    function closePopup() {
    }
    
    function dragElement(elmnt, handle) {
      var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    
      if (handle) { // True if handle is defined by the caller
        /* if present, the header is where you move the DIV from:*/
        handle.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) {
        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;
        
        if (parseInt(elmnt.style.top) < 0) {
          elmnt.style.top = 0;
        }
    
        if (parseInt(elmnt.style.left) < 0) {
          elmnt.style.left = 0;
        }
      }
    }
    
    dragElement(document.getElementById("elem"), 
    document.querySelector(".elemTitle"));
    <div id="elem" style="width: 185px;height: 117px; z-index:11; position:absolute; user-select: none">
        <div class="elemTitle">
        play some music?
        <button style="text-align:right; float:right;" onClick="closePopup()"> x </button>
        </div>
        <div id="musicplayer">
            <div>
                <marquee scrollamount="8" class="songtitle"></marquee>
            </div>
     
            <table class="controls">
                <tr>
                    <td>
                        <div class="prev-track" onclick="prevTrack()"><i class="fas fa-backward"></i></div>
                    </td>
                    <td>
                        <div class="playpause-track" onclick="playpauseTrack()" ><i class="fas fa-play"></i></div>
                    </td>
                    <td>
                        <div class="next-track" onclick="nextTrack()"><i class="fas fa-forward"></i></div>
                    </td>
                </tr>
            </table>
     
            <div class="seeking">
                <div class="current-time">00:00</div>
     
                <input type="range" min="1" max="100" value="0" class="seek_slider" onchange="seekTo()">
     
                <div class="total-duration">0:00</div>
            </div>
     
            <audio id="music" src=""></audio> 
        </div>