记录一段实现可拖拽、可自动吸附到边界的代码。
<!DOCTYPE html>
<html lang="en">
<head><style>body {overflow: hidden;}#pane {position: absolute;width: 45%;height: 45%;top: 20%;left: 20%;margin: 0;padding: 0;z-index: 99;border: 2px solid purple;background: #fefefe;}#title {font-family: monospace;background: purple;color: white;font-size: 16px;height: 22px;text-align: center;}#ghostpane {background: #999;opacity: 0.2;width: 45%;height: 45%;top: 20%;left: 20%;position: absolute;margin: 0;padding: 0;z-index: 98;-webkit-transition: all 0.25s ease-in-out;-moz-transition: all 0.25s ease-in-out;-ms-transition: all 0.25s ease-in-out;-o-transition: all 0.25s ease-in-out;transition: all 0.25s ease-in-out;}</style><title>测试div可拖拽</title><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<body>
<div>这里是测试文本
</div>
<div id="pane"><div id="title">属性配置</div>
</div>
<div id="ghostpane"></div>
<script>// Minimum resizable areavar minWidth = 400;var minHeight = 200;// Thresholdsvar FULLSCREEN_MARGINS = -10;var MARGINS = 4;// End of what's configurable.var clicked = null;var onRightEdge, onBottomEdge, onLeftEdge, onTopEdge;var rightScreenEdge, bottomScreenEdge;var preSnapped;var b, x, y;var redraw = false;var pane = document.getElementById('pane');var ghostpane = document.getElementById('ghostpane');function setBounds(element, x, y, w, h) {element.style.left = x + 'px';element.style.top = y + 'px';element.style.width = w + 'px';element.style.height = h + 'px';}function hintHide() {setBounds(ghostpane, b.left, b.top, b.width, b.height);ghostpane.style.opacity = 0;}// Mouse eventspane.addEventListener('mousedown', onMouseDown);document.addEventListener('mousemove', onMove);document.addEventListener('mouseup', onUp);// Touch eventspane.addEventListener('touchstart', onTouchDown);document.addEventListener('touchmove', onTouchMove);document.addEventListener('touchend', onTouchEnd);function onTouchDown(e) {onDown(e.touches[0]);e.preventDefault();}function onTouchMove(e) {onMove(e.touches[0]);}function onTouchEnd(e) {if (e.touches.length === 0) onUp(e.changedTouches[0]);}function onMouseDown(e) {onDown(e);e.preventDefault();}function onDown(e) {calc(e);var isResizing = onRightEdge || onBottomEdge || onTopEdge || onLeftEdge;clicked = {x: x,y: y,cx: e.clientX,cy: e.clientY,w: b.width,h: b.height,isResizing: isResizing,isMoving: !isResizing && canMove(),onTopEdge: onTopEdge,onLeftEdge: onLeftEdge,onRightEdge: onRightEdge,onBottomEdge: onBottomEdge};}function canMove() {return x > 0 && x < b.width && y > 0 && y < b.height && y < 30;}function calc(e) {b = pane.getBoundingClientRect();x = e.clientX - b.left;y = e.clientY - b.top;onTopEdge = y < MARGINS;onLeftEdge = x < MARGINS;onRightEdge = x >= b.width - MARGINS;onBottomEdge = y >= b.height - MARGINS;rightScreenEdge = window.innerWidth - MARGINS;bottomScreenEdge = window.innerHeight - MARGINS;}let e;function onMove(ee) {calc(ee);e = ee;redraw = true;}function animate() {requestAnimationFrame(animate);if (!redraw) return;redraw = false;if (clicked && clicked.isResizing) {if (clicked.onRightEdge) pane.style.width = Math.max(x, minWidth) + 'px';if (clicked.onBottomEdge) pane.style.height = Math.max(y, minHeight) + 'px';if (clicked.onLeftEdge) {var currentWidth = Math.max(clicked.cx - e.clientX + clicked.w, minWidth);if (currentWidth > minWidth) {pane.style.width = currentWidth + 'px';pane.style.left = e.clientX + 'px';}}if (clicked.onTopEdge) {var currentHeight = Math.max(clicked.cy - e.clientY + clicked.h, minHeight);if (currentHeight > minHeight) {pane.style.height = currentHeight + 'px';pane.style.top = e.clientY + 'px';}}hintHide();return;}if (clicked && clicked.isMoving) {if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) {// hintFull();setBounds(ghostpane, 0, 0, window.innerWidth, window.innerHeight);ghostpane.style.opacity = 0.2;} else if (b.top < MARGINS) {// hintTop();setBounds(ghostpane, 0, 0, window.innerWidth, window.innerHeight / 2);ghostpane.style.opacity = 0.2;} else if (b.left < MARGINS) {// hintLeft();setBounds(ghostpane, 0, 0, window.innerWidth / 2, window.innerHeight);ghostpane.style.opacity = 0.2;} else if (b.right > rightScreenEdge) {// hintRight();setBounds(ghostpane, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);ghostpane.style.opacity = 0.2;} else if (b.bottom > bottomScreenEdge) {// hintBottom();setBounds(ghostpane, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2);ghostpane.style.opacity = 0.2;} else {hintHide();}if (preSnapped) {setBounds(pane,e.clientX - preSnapped.width / 2,e.clientY - Math.min(clicked.y, preSnapped.height),preSnapped.width,preSnapped.height);return;}// movingpane.style.top = (e.clientY - clicked.y) + 'px';pane.style.left = (e.clientX - clicked.x) + 'px';return;}// This code executes when mouse moves without clicking// style cursorif (onRightEdge && onBottomEdge || onLeftEdge && onTopEdge) {pane.style.cursor = 'nwse-resize';} else if (onRightEdge && onTopEdge || onBottomEdge && onLeftEdge) {pane.style.cursor = 'nesw-resize';} else if (onRightEdge || onLeftEdge) {pane.style.cursor = 'ew-resize';} else if (onBottomEdge || onTopEdge) {pane.style.cursor = 'ns-resize';} else if (canMove()) {pane.style.cursor = 'move';} else {pane.style.cursor = 'default';}}animate();function onUp(e) {calc(e);if (clicked && clicked.isMoving) {// Snapvar snapped = {width: b.width,height: b.height};if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) {// hintFull();setBounds(pane, 0, 0, window.innerWidth, window.innerHeight);preSnapped = snapped;} else if (b.top < MARGINS) {// hintTop();setBounds(pane, 0, 0, window.innerWidth, window.innerHeight / 2);preSnapped = snapped;} else if (b.left < MARGINS) {// hintLeft();setBounds(pane, 0, 0, window.innerWidth / 2, window.innerHeight);preSnapped = snapped;} else if (b.right > rightScreenEdge) {// hintRight();setBounds(pane, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);preSnapped = snapped;} else if (b.bottom > bottomScreenEdge) {// hintBottom();setBounds(pane, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2);preSnapped = snapped;} else {preSnapped = null;}hintHide();}clicked = null;}
</script>
</body>
</html>
效果展示:
吸附效果:
结语
不得不说css和js用的好的话是可以实现很多好玩的功能的,只是我自己对这俩用的还没那么精通。
看到这个好玩的代码就赶紧记录下来,希望能帮助到需要的人吧。