<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
div {
background-color: pink;
width: 100px;
height: 100px;
position: absolute;
}
</style>
</head>
<body>
<div></div>
<script>
/**
* 拖拽效果
*
* 问题1:事件类型是什么?(拖拽3要素)
* => 鼠标按下
* => 鼠标移动
* => 鼠标抬起
* 问题2:对应事件类型 的 事件源是什么?
* => 鼠标按下
* => div
* => 鼠标移动
* => 当前文档/div(有瑕疵)
* => 鼠标抬起
* => div
* 问题3:移动距离是多少?
* 不是说单纯的鼠标移动到某一个坐标点,就代表移动多少
* 解决:
* 1。在鼠标按下的时候,记录元素本身的坐标
* 2。在鼠标移动的时候,重新获取最新的坐标
* var 移动距离 = 最新的坐标 - 最初的坐标
* 问题4:是直接将移动距离赋值给元素吗?
* 1.在鼠标按下的时候,记录元素本身的偏移量
* 2.将本身的偏移量与移动距离相加
* 3.将相加的和,赋值给元素
* */
// 0.获取元素
var oDiv = document.querySelector('div')
// 0.准备全局变量
var flag = false //用于控制鼠标移动事件是否执行
var startX = 0 //记录鼠标在按下时X轴的位置
var startY = 0 //记录鼠标在按下时Y轴的位置
var eleTop = 0 //记录鼠标在按下时 元素本身距离顶部的偏移量
var eleLeft = 0 //记录鼠标在按下时 元素本身距离左侧的偏移量
// 1.鼠标按下
oDiv.onmousedown = function(e) {
// console.log('鼠标按下事件触发')
flag = true
// 1.1 记录鼠标的坐标
startX = e.clientX
startY = e.clientY
// 1.2记录元素本身的偏移量
eleTop = oDiv.offsetTop
eleLeft = oDiv.offsetLeft
}
// 2.鼠标移动
document.onmousemove = function(e) {
if(flag === false) return
// console.log('鼠标移动事件触发')
// console.log(startX, startY)
// console.log(eleTop, eleLeft)
// 2.1获取最新坐标
var newX = e.clientX
var newY = e.clientY
// 2.2计算移动距离 === 最新坐标 - 最初坐标
var moveX = newX - startX
var moveY = newY - startY
// 2.3将本身的偏移量与移动距离相加
var x = eleLeft + moveX
var y = eleTop + moveY
// 2.4将相加的和,赋值给元素
oDiv.style.left = x + 'px'
oDiv.style.top = y + 'px'
}
// 3.鼠标抬起
oDiv.onmouseup = function() {
// console.log('鼠标抬起事件触发')
flag = false
}
/**
* 开关变量的逻辑:
* 1. 打开页面首次进入
* flag === false 然后鼠标移动事件 内部if条件成立 直接return不会执行函数内部代码
* 2.鼠标按下事件触发,将fLag的值修改为true
* fLag=-=true 然后鼠标移动事件内部if条件不成立,开始正常执行函数内部代码
* 3.鼠标抬起事件触发,将fLag的值修改为false
* fLag === false 然后鼠标移动时间内部i计条件成立。直接return 不会执行函数内部代码
* */