一、9种鼠标事件
DOM3
级事件中定义了9个鼠标事件。
mousedown
mouseup
click
dblclick
mouseover
mouseout
mouseenter
mouseleave
mousemove
页面中的所有元素都支持鼠标事件。除了
mouseenter
和mouseleave
,所有鼠标事件都会冒泡,都可以被取消。
可以对9种鼠标事件分为三类:
mousedown
,mousemove
,mouseup
: 按下,移动,释放鼠标。click
,dblclick
: 单击,双击鼠标。mouseover
,mouseout
:鼠标从一个元素上移入/移出(冒泡)。mouseenter
,mouseleave
: 鼠标从一个元素上移入/移出(不冒泡)。
二、mousedown
,mousemove
,mouseup
mousedown
: 按下任意鼠标键时触发(左键或者右键)。mousemove
: 鼠标光标在元素内移动时不断触发。mouseup
: 鼠标按钮被释放弹起时触发。
mousedown
,mousemove
,mouseup
都不能通过键盘触发。
2.1、使用Vue
指令实现ElementUI el-drawer
抽屉的拖拽调整宽度效果
因为ElementUI
的抽屉没有拖拽调整宽度的效果,可以通过mousedown
,mousemove
,mouseup
这三个事件自定义Vue
指令来实现。
- 定义CSS属性
/* 拖动CSS样式 左右 */
.drawer-resize-lr {
position: absolute;
width: 10px;
height: 100%;
}
/* 拖动CSS样式 上下 */
.drawer-resize-tb {
position: absolute;
width: 100%;
height: 10px;
}
- 定义Vue指令
/**
* elementUI抽屉拖拽指令 drawer-move.js
* ltr 从左往右
* rtl 从右往左
* ttb 从上往下
* btt 从下往上
*/
export default {
// 指令第一次绑定到元素时调用
bind(el, binding) {
if (!el.querySelector('.el-drawer')) return
// 定义传给指令的参数,默认从右往左
const dire = binding.arg || 'rtl'
// 自定义左右拖拽最小宽度
const dragMinWidth = 400
// 自定义上下拖拽最小高度
const dragMinHeight = 300
const parent = el.querySelector('.el-drawer')
// 定义位置样式
const posi = {
ltr: ';right:0;cursor:e-resize;',
rtl: ';left:0;cursor:w-resize;',
ttb: ';bottom:0;cursor:s-resize;',
btt: ';top:0;cursor:n-resize;'
}
// 创建span元素并设置样式,添加到parent元素下
const dragEl = document.createElement('span')
dragEl.className = dire === 'ltr' || dire === 'rtl' ? 'drawer-resize-lr' : 'drawer-resize-tb'
dragEl.style.cssText += posi[dire]
parent.appendChild(dragEl)
// 鼠标按下
dragEl.onmousedown = (e) => {
// x轴坐标
const disX = e.clientX
// y轴坐标
const disY = e.clientY
// .el-drawer元素宽度
const parentWidth = parent.offsetWidth
// .el-drawer元素高度
const parentHeight = parent.offsetHeight
// 通过事件委托定义鼠标移动事件
document.onmousemove = (ev) => {
// 定义拖拽最大宽度
const maxW = document.documentElement.clientWidth - 10
// 定义拖拽最大高度
const maxH = document.documentElement.clientHeight - 10
// 左移动距离
const moveLeft = ev.clientX - disX
// 上移动距离
const moveTop = ev.clientY - disY
// 左右抽屉
if (dire === 'rtl' || dire === 'ltr') {
// 根据打开方向计算拖拽宽度
let w = dire === 'rtl' ? parentWidth - moveLeft : parentWidth + moveLeft
// 边界处理
if (w < dragMinWidth) w = dragMinWidth
if (w > maxW) w = maxW
parent.style.width = `${w}px`
}
// 上下抽屉
if (dire === 'ttb' || dire === 'btt') {
// 根据打开方向计算拖拽高度
let h = dire === 'btt' ? parentHeight - moveTop : parentHeight + moveTop
// 边界判断
if (h < dragMinHeight) h = dragMinHeight
if (h > maxH) h = maxH
parent.style.height = `${h}px`
}
}
// 鼠标释放
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
}
}
}
}
- 使用方式
<el-drawer size="520px" :direction="direction" v-drawer-move:[direction] :visible="true"></el-drawer>
data() {
return {
direction: 'rtl' // ltr,rtl,ttb,btt
}
}
三、mouseover
,mouseout
mouseover
: 当鼠标移入某元素时触发。mouseout
: 当鼠标移出该元素时触发。
mouseover
和mouseout
事件不能通过键盘触发。这两个事件会冒泡,所以移入和移出其子元素时也会触发。
如下图定义父子元素,并添加事件:
<body id="body">
<div id="parent">
parent
<div id="child">child</div>
</div>
parent.addEventListener('mouseover', (e) => {
console.log('mouseover---->', e.target.firstChild.textContent.trim())
})
parent.addEventListener('mouseout', (e) => {
console.log('mouseout---->', e.target.firstChild.textContent.trim())
})
</body>
从parent
元素到child
元素,再从child
回到parent
然后离开,元素移动到另一个元素(包括后代元素),它将离开前一个元素,所以先离开后进入。所以控制台输出如下:
可以把一个元素的移入和移出比做一对双胞胎一样,他们两个总是前后在一起出现。
3.1、 relatedTarget
属性
对mouseover
和mouseout
这两个事件都涉及从一个元素的边界之内把光标移到另一个元素的边界之内。这些事件很特别,因为它们具有relatedTarget
属性。此属性是对target
的补充。当鼠标从一个元素离开并去往另一个元素时,其中一个元素就变成了target
,另一个就变成了relatedTarget
。
DOM
通过event
对象的relatedTarget
属性提供了相关元素的信息。这个属性只有在mouseover
和mouseout
事件发生时才包含值,其他所有事件的这个属性的值都是null
。
对于mouseover
而言:
event.target
:是鼠标移过的那个元素。event.relatedTarget
:是鼠标来自的那个元素(relatedTarget → target)。
<body id="body">
<div id="parent">
parent
<div id="child">child</div>
</div>
parent.addEventListener('mouseover', (e) => {
console.log('target---->', e.target.id)
console.log('relatedTarget---->', e.relatedTarget.id)
})
</body>
从外到内移入:从body
元素移入到parent
元素再到child
元素,控制台输出如下:
对于mouseout
而言:
event.target
:鼠标离开的元素。event.relatedTarget
:离开目标元素时,鼠标进入的元素。
<body id="body">
<div id="parent">
parent
<div id="child">child</div>
</div>
parent.addEventListener('mouseout', (e) => {
console.log('target---->', e.target.id)
console.log('relatedTarget---->', e.relatedTarget.id)
})
</body>
从内到外移出:从child
元素移出到parent
元素再到body
元素,控制台输出如下:
结合mouseover
和mouseout
监听移动:
<body id="body">
<div id="parent">
parent
<div id="child">child</div>
</div>
box.addEventListener('mouseover', (e) => {
console.log('target---->', e.target.id)
console.log('relatedTarget---->', e.relatedTarget.id)
console.warn('mouseover----> END')
console.log('\n')
})
box.addEventListener('mouseout', (e) => {
console.warn('mouseout----> START')
console.log('target---->', e.target.id)
console.log('relatedTarget---->', e.relatedTarget.id)
console.warn('mouseout----> END')
console.log('\n')
})
</body>
控制台输出如下:
四、mouseenter
,mouseleave
-
mouseenter
: 当鼠标移入某元素时触发。 -
mouseleave
: 当鼠标移出某元素时触发。
mouseenter
,mouseleave
这两个事件不冒泡。
如下图定义父子元素:
<body id="body">
<div id="parent">
parent
<div id="child">child</div>
</div>
parent.addEventListener('mouseenter', (e) => {
console.log('mouseenter---->', e.target.firstChild.textContent.trim())
})
parent.addEventListener('mouseleave', (e) => {
console.log('mouseleave---->', e.target.firstChild.textContent.trim())
})
</body>
从parent
元素到child
元素,再从child
回到parent
然后离开,控制台输出如下:
五、click,dblclick事件
click
: 单击鼠标主键(通常是左键)或按键盘回车键时触发,键盘和鼠标都可以触发onclick
事件。dblclick
: 双击鼠标主键(通常是左键)时触发。
六、 参考链接
zh.javascript.info/mousemove-m…