鼠标跟随案例
/*
案例 - 鼠标跟随
需求:
+ 默认, 提示盒子是隐藏
+ 当鼠标移入哪一个 li 的时候, 哪一个 li 对应的提示盒子显示
+ 当鼠标移出哪一个 li 的时候, 哪一个 li 对应的提示盒子隐藏
+ 当鼠标在哪一个 li 内移动的时候, 哪一个 li 对应的提示盒子跟随鼠标移动
问题1: 什么时候出现效果 ?
+ 鼠标移入
+ 鼠标移出
+ 鼠标移动
问题2: 在哪出现效果 ?
+ 每一个 li 标签内
问题3: 在什么位置坐什么事情 ?
3-1. 鼠标移入事件内
=> 移入的这个 li 的对应的 p 显示
3-2. 鼠标移出事件内
=> 移出的这个 li 的对应的 p 隐藏
3-3. 鼠标移动事件内
=> 拿到鼠标光标坐标位置 ? offset
=> 赋值给 li 对应的 p 的 left 和 top 样式
分析问题
+ 抖动
+ 当 p 出现的时候, 相对于光标和 li 之间隔了一个 p 标签
+ 此时拿到的 offset 坐标就是相对于 p 的, 也就是 0 0 位置
解决方案
+ 方案1: 让 p 出现的位置相对光标位置右下移动
+ 方案2: 在 p 身上不出现任何效果, 直接穿透下去(依赖一个 css 样式)
*/
<!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>
* {
margin: 0;
padding: 0;
list-style: none;
}
ul {
width: 500px;
margin: 50px;
}
li {
width: 100%;
height: 60px;
line-height: 60px;
font-size: 30px;
border: 1px solid #333;
margin-bottom: 10px;
position: relative;
}
p {
position: absolute;
left: 500px;
top: 300px;
width: 300px;
height: 150px;
background-color: pink;
display: none;
/* 认识事件在我神身上不会触发, 我不作为事件目标 */
pointer-events: none;
font-size: 20px;
line-height: 20px;
z-index: 999;/*提高层局*/
/* z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
注释:元素可拥有负的 z-index 属性值。
注释:Z-index 仅能在定位元素上奏效(例如 position:absolute;)!
说明
该属性设置一个定位元素沿 z 轴的位置,z 轴定义为垂直延伸到显示区的轴。如果为正数,则离用户更近,为负数则表示离用户更远。 */
}
</style>
</head>
<body>
<ul>
<li>我是标题1
<p>我是提示内容我是提示内容我是提示内容我是提示内容我是提示内容我是提示内容</p>
</li>
<li>我是标题2
<p style="background-color: orange;">我是提示内容我是提示内容我是提示内容我是提示内容我是提示内容我是提示内容</p>
</li>
<li>我是标题3
<p style="background-color: skyblue;">我是提示内容我是提示内容我是提示内容我是提示内容我是提示内容我是提示内容</p>
</li>
</ul>
<script>
// 0. 获取元素
var lis = document.querySelector('ul>li')
var lis = document.querySelectorAll('li')
// 1. 循环给每一个 li 绑定 鼠标三个事件
lis.forEach(function(item){
// 1-1. 绑定鼠标移入事件 item.addEventListener('mouseover',overHandler)
// 1-2. 绑定鼠标移出事件
item.addEventListener('mouseout',outHandler)
// 1-3. 绑定鼠标移动事件
item.addEventListener('mousemove',moveHandler)
})
// 2-1. 鼠标移入事件处理函数
function overHandler() {
// 移入的 li 是谁 ?
// console.log(this)
// 对应的 p
// console.log(this.firstElementChild)
this.firstElementChild.style.display = 'block'
}
// 2-2. 鼠标移出事件处理函数
function outHandler() {
// 移入的 li 是谁 ?
// console.log(this)
// 对应的 p
// console.log(this.firstElementChild)
this.firstElementChild.style.display = 'none'
}
// 2-3. 鼠标移动事件处理函数
function moveHandler(e) {
// 拿到 offset 一组坐标
// 因为 p 是相对于 li 定位的
// 我们最好也拿到相对于 li 的坐标位置
var x = e.offsetX
var y = e.offsetY
// 赋值
this.firstElementChild.style.left = x + 'px'
this.firstElementChild.style.top = y + 'px'
}
</script>
</body>
</html>