Drag and move element (Only frame moves at first)

by Sasabee

HTML

<body>
  <div class="box"></div>
</body>

CSS

body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100vh;
  background-color: #1B1C1E;
  overflow: hidden;
}
.box {
  background-color: #FDFF3A;
  width: 50px;
  height: 50px;
}
.box.moving {
  background: 0;
  box-shadow: 0px 0px 2px 0px white;
  outline: 1px solid #CCC;
}

JavaScript

const touchEventsEnabled = Boolean(window.ontouchstart);
const el = document.querySelector('.box');

el.addEventListener(touchEventsEnabled ? 'touchstart' : 'mousedown', (e)=>{
	el.style.position || (el.style.position = 'absolute');

	const clone = el.cloneNode();
	el.before(clone);
	el.classList.toggle('moving');

	const targetRect = e.target.getBoundingClientRect();

	const rightLimit = document.documentElement.clientWidth - targetRect.width;
	const bottomLimit = document.documentElement.clientHeight - targetRect.height;
	const leftLimit = 0;
	const topLimit = 0;

	const gapX = e.clientX - targetRect.left;
	const gapY = e.clientY - targetRect.top;

	const mousemoveCallback = (e)=>{
		let currentX = e.pageX - gapX;
		currentX < leftLimit && (currentX = leftLimit);
		rightLimit < currentX && (currentX = rightLimit);

		let currentY = e.pageY - gapY;
		currentY < topLimit && (currentY = topLimit);
		bottomLimit < currentY && (currentY = bottomLimit);

		el.style.left = currentX + 'px';
		el.style.top = currentY + 'px';
	};

	const mouseupCallback = (e)=>{
		document.removeEventListener(touchEventsEnabled ? 'touchmove' : 'mousemove', mousemoveCallback);
		el.removeEventListener(touchEventsEnabled ? 'touchend' : 'mouseup', mouseupCallback);

		el.classList.toggle('moving');
		clone.remove();
	};

	document.addEventListener(touchEventsEnabled ? 'touchmove' : 'mousemove', mousemoveCallback);
	el.addEventListener(touchEventsEnabled ? 'touchend' : 'mouseup', mouseupCallback);
});