1. 三大家族简介
DOM 提供的距离监听的API:
- offset
属性 | 属性详解 |
---|---|
div.offsetWidth | 元素自身宽的获取,只读属性,设置请使用 div.style.width |
div.offsetHeight | 元素自身高的获取,只读属性,设置请使用 div.style.height |
div.offsetLeft | 元素与带有定位,离自己最近的父级的left值 |
div.offsetTop | 元素与带有定位,离自己最近的父级的top值 |
- scroll
属性 | 属性详解 |
---|---|
div.scrollWidth | 元素内容的宽 |
div.scrollHeight | 元素内容的高 |
div.scrollTop | 元素被卷去的高度(滚动条) |
- client
属性 | 属性详解 |
---|---|
div.clientWidth | 窗口可视区宽 |
div.clientHeight | 窗口可视区高 |
event.clientX | 当前事件对象触发点与屏幕左侧的距离 |
event.clientY | 当前事件对象触发点与屏幕上方的距离 |
2. 常见使用案例
- 鼠标滚轮滚动事件监听:
window.onscroll = function () { var top = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; //后面对top进行判定 }
- 响应式布局监听:
window.onresize = function () { //对clientWidth 进行监听 }
- 鼠标在盒子中的坐标监听:
box.onmousemove = function (event) { var event = window.event || event; var x = event.clientX - this.offsetLeft; var y = event.clientY - this.offsetTop; //对x, y 进行监听 }
3. 拖拽的实现
简单拖拽的应用场景为:滑块拖拽、提示框浮层等,复杂的拖拽需求核心也是三大家族配合鼠标在当前点的坐标(event.clientX)进行计算,加svg画线、地图等实现。
下面代码为提示框在固定宽高盒子中的拖拽:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.test-box {
width: 1300px;
height: 400px;
margin: 30px auto;
border: 1px solid #ccc;
position: relative;
}
.test-box .move-box {
width: 300px;
height: 200px;
background: #eee;
cursor: move;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="test-box">
<div class="move-box"></div>
</div>
</body>
<script>
// move-box 移动
var moveBox = document.getElementsByClassName('move-box')[0];
// test-box 为外层限制盒子
var testBox = document.getElementsByClassName('test-box')[0];
moveBox.onmousedown = function (event) {
var event = event || window.event;
var initX = (event.pageX || event.clientX + document.documentElement.scrollLeft) - this.offsetLeft;
var initY = (event.pageY || event.clientY + document.documentElement.scrollTop) - this.offsetTop;
document.onmousemove = function (event) {
var event = event || window.event;
var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
// 限制判断条件
var left, top;
if (pageX - initX < 0) {
left = 0;
} else if (pageX - initX > testBox.offsetWidth - moveBox.offsetWidth - 2) {
// 多减去2px是因为外层盒子加了边框
left = testBox.offsetWidth - moveBox.offsetWidth - 2;
} else {
left = pageX - initX;
}
if (pageY - initY < 0) {
top = 0;
} else if (pageY - initY > testBox.offsetHeight - moveBox.offsetHeight - 2) {
top = testBox.offsetHeight - moveBox.offsetHeight - 2;
} else {
top = pageY - initY;
}
moveBox.style.left = left + 'px';
moveBox.style.top = top + 'px';
}
}
document.onmouseup = function () {
document.onmousemove = null;
}
</script>
</html>
效果图如下:
4. 拖放
HTML5 里面新增了drag系列的API,用于实现拖放功能,列表顺序拖动切换,表格表头拖动切换,甚至于对可视化拖拉拽组件生成HTML页面类似项目提供支持。
drag常用API如下:
事件 | 事件说明 |
---|---|
dragstart | 当用户开始拖动一个元素或者一个选择文本的时候dragstart事件就会触发 |
dragend | 拖动操作结束时触发 |
dragover | 拖动过程不断触发,阻止默认事件 |
dragexit | 元素不是被拖动目标时 |
dragenter | a拖到b中的时候,b触发 |
dragleave | a拖到b,不释放鼠标,再拖到c,离开b的时候,b触发 |
drop | 当一个元素或是选中的文字被拖拽释放到一个有效的释放目标位置时 |
简单案例如下:
<!DOCTYPE html>
<html>
<head>
<title>HTML5拖拽</title>
<meta charset="utf-8">
<style>
#div1 {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
#drag1 {
width: 200px;
height: 50px;
background: #4a90e2;
}
</style>
</head>
<body>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<div id="drag1" draggable="true" ondragstart="drag(event)"></div>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
// 设置拖拽元素携带的数据
ev.dataTransfer.setData("Text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
// 获取拖拽元素携带的数据
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</body>
</html>
本文只提供drag常用API列表,具体案例与学习请参考:用两种不同的姿势来实现拖动排序 ,学习使用强烈推荐。