Ad

Move Multiple Divs On The Same Page

- 1 answer

My problem is when I add a mousemove listener on document, all divs are moving but when I add a mousemove listener on my element, I have to move the cursor slowly.

Here is my code :

let componentsItems = document.getElementsByClassName("componentItem");
[].forEach.call(componentsItems, function (componentItem) {
    componentItem.addEventListener("click", function (event) {
        let selectedComponent = getComponentToDisplay(event.target.getAttribute("data-exchange"));

        let mapContainer = document.getElementById("mapContainer");
        let mainElement = document.createElement("div");
        mainElement.innerHTML = "test";

        mainElement.style.position = "absolute";
        mapContainer.appendChild(mainElement);

        mainElement.addEventListener("mouseup", function (e) {
            isDown = false;
        });

        mainElement.addEventListener("mousedown", function (e) {
            isDown = true;
            offset = [
                mainElement.offsetLeft - e.clientX,
                mainElement.offsetTop - e.clientY
            ];
        });

        document.addEventListener("mousemove", function (e) {
            e.preventDefault();
            mousePosition = {
                x: e.clientX,
                y: e.clientY
            };

            let left = (mousePosition.x + offset[0]);
            let top = (mousePosition.y + offset[1]);
            if(isDown){
                if(mapContainer.offsetTop < top && mapContainer.offsetWidth > left){
                    mainElement.style.left =  left + 'px';
                    mainElement.style.top = top + 'px';
                }
            }
        });
    });
});

For each component in my menu, I add an onclick listener to appendChild element in the "MapContainer" div.

Ad

Answer

The drag and drop problem.

The problem is you are attaching multiple mousemove listeners to document, and each one with every one of the different mainElements.

The solution:

Remember which element we are about to move.

mainElement.addEventListener("mousedown", function (e) {
  isDown = true;
  element = mainElement;
  offset = [
    mainElement.offsetLeft - e.clientX,
    mainElement.offsetTop - e.clientY
  ];
});

On the outter scope (outside foreach) create a unique mousemove event listener, and update the element that we mousedowned before.

document.addEventListener("mousemove", function (e) {
  e.preventDefault();
  mousePosition = {
    x: e.clientX,
    y: e.clientY
  };

  let left = (mousePosition.x + offset[0]);
  let top = (mousePosition.y + offset[1]);
  if(isDown){
    if(mapContainer.offsetTop < top && mapContainer.offsetWidth > left){
      element.style.left =  left + 'px';
      element.style.top = top + 'px';
    }
  }
});

Other ways to solve this problem is to create (and delete) the eventlistener on the mousedown and mouseup event handlers respectively. But I believe it's less efficient and definitely more complicated.

Ad
source: stackoverflow.com
Ad