<html>
<head>
<link rel="stylesheet" href="./jquery-ui-1.12.1/jquery-ui.min.css" />
<title>实现div拖拽时出现辅助线,以方便和其它div很容易的对齐title>
head>
<body>
<div class="container">
<div class="draggable">第一个divdiv>
<div class="draggable">第二个divdiv>
<div class="draggable">第三个divdiv>
<div class="draggable">第四个divdiv>
<div class="draggable">第五个divdiv>
<div class="draggable">第六个divdiv>
<div id="guide-h" class="guide">div>
<div id="guide-v" class="guide">div>
div>
<script src="./jquery-ui-1.12.1/external/jquery/jquery.js">script>
<script src="./jquery-ui-1.12.1/jquery-ui.min.js">script>
<script type="text/javascript">
var MIN_DISTANCE = 8 //捕获的最小距离
var guides = [] // 指标拖动辅助标线
var innerOffsetX, innerOffsetY
$('.draggable').draggable({
start: function(event, ui) {
guides = $.map($('.draggable').not(this), computeGuidesForElement)
// offsetX、offsetY:源元素(srcElement)的X, Y坐标
innerOffsetX = event.offsetX
innerOffsetY = event.offsetY
},
drag: function(event, ui) {
// 迭代所有的guids,记住最近的h和v guids
var guideV,
guideH,
distV = MIN_DISTANCE + 1,
distH = MIN_DISTANCE + 1,
offsetV,
offsetH
var chosenGuides = {
top: {
dist: MIN_DISTANCE + 1
},
left: {
dist: MIN_DISTANCE + 1
}
}
var $t = $(this)
// pageX、pageY:文档坐标x、y
var pos = {
// top: event.pageY - innerOffsetY,
// left: event.pageX - innerOffsetX
top: event.clientY - innerOffsetY,
left: event.clientX - innerOffsetX
}
// outerHeight、outerWidth:整个浏览器的高度、宽度
var w = $t.outerWidth() - 1
var h = $t.outerHeight() - 1
var elemGuides = computeGuidesForElement(null, pos, w, h)
$.each(guides, function(i, guide) {
$.each(elemGuides, function(i, elemGuide) {
if (guide.type == elemGuide.type) {
var prop = guide.type == 'h' ? 'top' : 'left'
var d = Math.abs(elemGuide[prop] - guide[prop])
if (d < chosenGuides[prop].dist) {
chosenGuides[prop].dist = d
chosenGuides[prop].offset = elemGuide[prop] - pos[prop]
chosenGuides[prop].guide = guide
}
}
})
})
if (chosenGuides.top.dist <= MIN_DISTANCE) {
$('#guide-h')
.css('top', chosenGuides.top.guide.top)
.show()
ui.position.top = chosenGuides.top.guide.top - chosenGuides.top.offset
} else {
$('#guide-h').hide()
ui.position.top = pos.top
}
if (chosenGuides.left.dist <= MIN_DISTANCE) {
$('#guide-v')
.css('left', chosenGuides.left.guide.left)
.show()
ui.position.left = chosenGuides.left.guide.left - chosenGuides.left.offset
} else {
$('#guide-v').hide()
ui.position.left = pos.left
}
},
stop: function(event, ui) {
$('#guide-v, #guide-h').hide()
}
})
/**
* 计算 DOM 元素辅助线
* @param {String, Object} elem DOM 选择器
* @param {Object} pos 位置坐标
* @param {Number} w 宽度
* @param {Number} h 高度
* @returns {Array} 辅助线对象数组
*/
function computeGuidesForElement(elem, pos, w, h) {
if (elem != null) {
var $t = $(elem)
// offset - 返回当前元素的偏移量
pos = $t.offset()
w = $t.outerWidth() - 1
h = $t.outerHeight() - 1
}
// type,方向类型,h - 垂直方向;v - 水平方向。
const guids = [
// 垂直方向 - 顶端对齐线
{ type: 'h', left: pos.left, top: pos.top },
// 垂直方向 - 中心对齐线
{ type: 'h', left: pos.left, top: pos.top + h / 2 },
// 垂直方向 - 中心对齐线
{ type: 'h', left: pos.left, top: pos.top + h },
// 水平方向 - 左侧对齐线
{ type: 'v', left: pos.left, top: pos.top },
// 水平方向 - 中心对齐线
{ type: 'v', left: pos.left + w / 2, top: pos.top },
// 水平方向 - 左侧对齐线
{ type: 'v', left: pos.left + w, top: pos.top }
]
return guids
}
script>
<style type="text/css">
* {
padding: 0px;
margin: 0px;
}
body {
height: 100%;
overflow-x: hidden;
overflow-y: hidden;
}
.container {
width: 100vw;
min-height: 90vh;
margin: 0px auto;
position: relative;
overflow: auto;
border-bottom: 1px gray solid;
}
.draggable {
width: 200px;
height: 100px;
border: 1px solid #ccc;
display: inline-block;
cursor: move;
position: absolute !important;
top: 0px;
left: 0px;
}
.guide {
display: none;
position: absolute;
left: 0;
top: 0;
}
#guide-h {
border-top: 1px red solid;
width: 100%;
}
#guide-v {
border-left: 1px red solid;
height: 100%;
}
style>
body>
html>