<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>实现div拖拽时出现辅助线,以方便和其它div很容易的对齐,实现简单布局器</title>
<link rel="stylesheet" href="./jquery-ui-1.12.1/jquery-ui.min.css" />
</head>
<body>
<!-- 网格线 -->
<div id="grid-line"></div>
<div class="container">
<!-- 拖动辅助线 -->
<div id="guide-h" class="guide"></div>
<div id="guide-v" class="guide"></div>
<div class="draggable"></div>
<div class="draggable" style="background-color: blanchedalmond;"></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>
const gridSpace = 50
// 拖拽部件选项
const draggableOption = {
// 约束在指定元素或区域的边界内拖拽
containment: '.container',
// 鼠标按下后拖拽开始前必须移动的距离,以像素计。该选项可以防止点击在某个元素上时不必要的拖拽
distance: 10,
// 当被拖拽时助手(helper)的不透明度
opacity: 0.5,
// 如果设置为 true,当拖拽时容器会自动滚动
scroll: true,
// 从要滚动的视区边缘起的距离,以像素计。距离是相对于指针的,不是相对于 draggable。如果 scroll 选项是 false 则忽略
scrollSensitivity: 20,
// 当鼠标指针获取到在 scrollSensitivity 距离内时,窗体滚动的速度。如果 scroll 选项是 false 则忽略
scrollSpeed: 100,
// 对齐拖拽助手(helper)到网格,每个 x 和 y 像素。数组形式必须是 [ x, y ]
grid: [gridSpace, gridSpace],
// 如果设置为 true,在每次鼠标移动(mousemove)时都会计算所有可放置的位置。注意:这解决了高度动态的问题,但是明显降低了性能
// refreshPositions: true,
// 拖拽操作期间的 CSS 光标
cursor: 'move',
// 元素是否对齐到其他元素
snap: true,
// 从要发生对齐的对齐元素边缘起的距离,以像素计。如果 snap 选项是 false 则忽略
snapTolerance: 20
}
// 缩放部件选项
const resizeableOption = {
// 约束在指定元素或区域的边界内拖拽
containment: '.container',
// 当用户鼠标没有悬浮在元素上时是否隐藏手柄
autoHide: true,
// 把可调整尺寸元素对齐到网格,每个 x 和 y 像素。数组形式必须是 [ x, y ]
grid: [gridSpace, gridSpace],
// 如果设置为 true,则为调整尺寸显示一个半透明的辅助元素
// ghost: true
// grid: 50
// resizable 允许被调整到的最小宽度
minWidth: 50,
// resizable 允许被调整到的最小高度
minHeight: 50
}
$(function() {
// 初始化组件拖拽、缩放
initComponent('.draggable')
})
// 初始化组件拖拽、缩放
function initComponent(selector) {
$(selector)
// 拖拽部件文档:https://www.jqueryui.org.cn/api/3722.html
.draggable(
Object.assign(draggableOption, {
/**
* 在拖拽期间当鼠标移动时触发
*/
drag: function(event, ui) {
const x = ui.position.left
const y = ui.position.top
const containerHeight = $('.container').height() + $('.container').scrollTop()
const containerWidth = $('.container').width() + $('.container').scrollLeft()
initGrid()
$('#guide-v').css({ height: containerHeight + 'px', left: x })
$('#guide-h').css({ width: containerWidth + 'px', top: y })
$('#guide-v,#guide-h').show()
},
/**
* 当拖拽停止时触发
*/
stop: function(event, ui) {
$('.container .grid-line').remove()
$('#guide-v,#guide-h').hide()
}
})
)
// 缩放部件文档:https://www.jqueryui.org.cn/api/3725.html
.resizable(
Object.assign(resizeableOption, {
/**
* 在调整尺寸期间当调整手柄拖拽时触发
* @param {Event} event 事件对象
* @param {Object} ui 拖拽 ui 元素
* helper - jQuery 对象,表示被调整尺寸的助手(helper)
* originalElement - jQuery 对象,表示被包裹之前的原始元素
* originalPosition - resizable 调整前的位置,表示为 { top, left }
* originalSize - resizable 调整前的尺寸,表示为 { width, height }
* position - 助手(helper)的当前 CSS 位置,比如 { top, left } 对象
* size - 助手(helper)的当前大小,比如 { top, left } 对象
*/
resize: function(event, ui) {
initGrid()
},
/**
* 当调整尺寸操作停止时触发
*/
stop: function(event, ui) {
$('.container .grid-line').remove()
}
})
)
}
function initGrid() {
const containerHeight = $('.container').height() + $('.container').scrollTop()
const containerWidth = $('.container').width() + $('.container').scrollLeft()
$('.container .grid-line').remove()
let lineTop = 0
while (lineTop < containerHeight) {
let gridLine = $('#grid-line').clone()
gridLine.removeAttr('id')
gridLine.addClass('grid-line')
gridLine.addClass('grid-line-h')
gridLine.attr('top', lineTop)
gridLine = gridLine[0]
lineTop += gridSpace
gridLine.style.top = lineTop + 'px'
gridLine.style.left = '0px'
gridLine.style.width = containerWidth + 'px'
gridLine.style.height = '1px'
$('.container').append(gridLine)
}
let lineLeft = 0
while (lineLeft < containerWidth) {
let gridLine = $('#grid-line').clone()
gridLine.removeAttr('id')
gridLine.addClass('grid-line')
gridLine.addClass('grid-line-v')
gridLine.attr('left', lineLeft)
gridLine = gridLine[0]
lineLeft += gridSpace
gridLine.style.top = '0px'
gridLine.style.left = lineLeft + 'px'
gridLine.style.width = '1px'
gridLine.style.height = containerHeight + 'px'
$('.container').append(gridLine)
}
}
</script>
<style>
.container {
/* margin-top: 100px; */
top: 20px;
min-height: 700px;
/* padding-bottom: 100px; */
position: relative;
/* 修复拖拽元素吸附到其他元素时超出容器区域 */
overflow: scroll;
/* background-color: gray; */
border: 1px #c0c0c0 solid;
z-index: 0;
}
.container .grid-line {
position: absolute;
z-index: 0;
/* border: 1px red solid; */
}
.container .grid-line-h {
border-top: 1px dashed rgb(236, 236, 236);
/* border-top: 1px dashed rgb(255, 0, 0); */
width: 100%;
}
.container .grid-line-v {
border-left: 1px dashed rgb(236, 236, 236);
/* border-left: 1px dashed rgb(255, 0, 0); */
height: 100%;
}
.draggable {
width: 150px;
height: 150px;
background-color: gray;
position: absolute;
top: 0px;
left: 0px;
z-index: 1;
}
.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>
嘴角上扬,记得微笑