1
\$\begingroup\$

Currently my code is based around mouse events so that it is easier to test but I will be swapping these to touch events once I have had the code reviewed. The idea of the UX is that you need to mousedown for 500ms until you can move the spot (similar to that of iOS when re-arranging apps on the homescreen). Then the spot shows you it's in a movable state then you can drop it.

The code works exactly as I want it to but I can't help but think that I have over-engineered it. This is why I have posted for review.

Codepen Link

const spotState = {
  moveable: false
}

const spotEL = document.getElementById('spot');
const statusEL = document.getElementById('status');

spotEL.onmouseenter = function() {
  statusEL.innerHTML = "Enter";
  clearTimeout(spotState.mouseDownTimer);
  spotState.mouseDownTimer = null;
  spotState.moveable = false;
  spotState.moving = false;
  spotEL.classList.remove('moving'); 
  spotState.clear && spotState.clear();
}

spotEL.onmouseleave = function() {
  statusEL.innerHTML = "Leave";
  clearTimeout(spotState.mouseDownTimer);
  spotState.mouseDownTimer = null;
  spotState.moveable = false;
  spotState.moving = false;
  spotEL.classList.remove('moving');
  spotState.clear && spotState.clear();
}

spotEL.onmousedown = function(event) {
  spotState.mouseDownTimer = setTimeout(function(){
    statusEL.innerHTML = "Down";
    spotEL.classList.add('moving'); 
    spotState.moveable = true
    spotState.mouseDownTimer = null
    let shiftX = event.clientX - spot.getBoundingClientRect().left;
    let shiftY = event.clientY - spot.getBoundingClientRect().top;

    moveAt(event.pageX, event.pageY);

    function moveAt(pageX, pageY) {
      if (spotState.moveable || spotState.moving) {
        spotState.moving = true;
        spotEL.style.left = pageX - shiftX + 'px';
        spotEL.style.top = pageY - shiftY + 'px';
      }
    };

    function onMouseMove(event) {
      statusEL.innerHTML = "Move";
      moveAt(event.pageX, event.pageY);
    };

    document.addEventListener('mousemove', onMouseMove);
    spotState.clear = function() {
      document.removeEventListener('mousemove', onMouseMove);
    }
  }, 350);

  spotEL.onmouseup = function() {
    statusEL.innerHTML = "Up";
    clearTimeout(spotState.mouseDownTimer);
    spotEL.classList.remove('moving'); 
    spotEL.onmouseup = null;
    spotState.moving = false;
    spotState.moveable = false;
    spotState.mouseDownTimer = null;
    spotEL.onmousemove = null;
    spotState.clear && spotState.clear();
  };
};

spotEL.ondragstart = function() {
  return false;
};
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.