首先图解js中clientX,clientY,offsetX,offsetY
- clientX: 表示当前鼠标距离浏览器X轴的距离
- clientY: 表示当前鼠标距离浏览器Y周的距离
- offsetX: 表示当前鼠标在DOM元素内,并且距离DOM元素左侧的距离
- offsetY: 表示当前鼠标在DOM元素内距离元素本身顶部的距离
属性说明:
案例:移动图标
- html结构
<template>
<div
id="icons"
class="float_box"
>
<img
class="customerServiceLogo"
src="../assets/header/serviceFloat.png"
alt=""
@mouseover="handleover"
@click="handleUrlPage"
>
<div class="float_content" :class="[active_float, triangle]">
<ul>
<li>
<i class="el-icon-phone-outline" size="20" />
<div>
<p>客服电话</p>
</div>
</li>
<li>
<i class="el-icon-message" />
<div>
<p>电子邮箱</p>
</div>
</li>
<li class="hover_style" @click="handleUrlPage">
<i class="el-icon-service" />
<div>
<p>客服工单</p>
<p>周一至周五 9:00-18:00</p>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
let startTime = 0
let endTime = 0
let startL = 0
let endL = 0
let endH = 0
let startH = 0
import { Base64 } from 'js-base64'
import { localStorage } from '@/utils/common'
export default {
data() {
return {
active_float: '',
triangle: '',
isClick: true
}
},
mounted() {
this.$nextTick(() => {
let icons = document.querySelector('#icons')
if (icons) {
icons.addEventListener('mousedown', this.handleStart)
icons.addEventListener('mouseup', () => {
let dates = new Date()
endTime = dates.getTime() // 时间戳
// let timeData = Number(endTime) - Number(startTime)
let widthDistance = startL - endL
widthDistance = Math.abs(widthDistance)
let heightDistance = startH - endH
heightDistance = Math.abs(heightDistance)
if (widthDistance == startL && heightDistance == startH) {
this.isClick = true
} else if (widthDistance > 0 && heightDistance > 0) {
this.isClick = false
} else {
this.isClick = true
}
document.onmousemove = null
})
}
})
},
methods: {
range(loc, min, max) {
if (loc > max) {
return max
} else if (loc < min) {
return min
} else {
return loc
}
},
handleover(e) {
if (e.clientX > document.documentElement.clientWidth / 2) {
this.active_float = 'left'
this.triangle = 'triangle_left'
if (e.clientY < document.documentElement.clientHeight / 2) {
this.active_float = 'top'
this.triangle = 'triangle_top'
}
} else {
this.active_float = 'right'
this.triangle = 'triangle_right'
if (e.clientY > document.documentElement.clientHeight / 2) {
this.active_float = 'bottom'
this.triangle = 'triangle_bottom'
} else {
this.active_float = 'btn'
this.triangle = 'triangle_btn'
}
}
},
handleStart(e) {
let date = new Date()
startTime = date.getTime() // 时间戳
e.preventDefault()
e.stopPropagation()
let t = this
let icons = document.querySelector('#icons')
let eX = e.clientX
let eY = e.clientY
let disX = eX - icons.offsetLeft
let disY = eY - icons.offsetTop
let l = e.clientX - disX
startL = e.clientX - disX
let h = e.clientY - disY
startH = e.clientY - disY
document.onmousemove = function(ev) {
this.isClick = false
l = ev.clientX - disX
endL = ev.clientX - disX
h = ev.clientY - disY
endH = ev.clientY - disY
let windowWidth = document.documentElement.clientWidth
let windowHeight = document.documentElement.clientHeight
l = t.range(l, 0, windowWidth - icons.offsetWidth)
h = t.range(h, 0, windowHeight - icons.offsetHeight)
icons.style.left = `${l}px`
icons.style.top = `${h}px`
}
},
handleUrlPage() {
// 点击事件
}
}
}
</script>
<style lang="scss" scoped>
.float_box {
bottom: 100px;
position: fixed;
width: 50px;
height: 50px;
right: 0;
z-index: 9999;
.customerServiceLogo {
width: 50px;
height: 50px;
border-radius: 50%;
}
.customerServiceLogo:hover {
cursor: pointer;
}
.float_content {
display: none;
width: 300px;
border-radius: 8px;
// height: 240px;
background: #fff;
border-radius: 8px;
border: 1px solid #ebeef5;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
ul {
display: flex;
flex-direction: column;
height: 100%;
padding: 10px 0;
li {
color: #001a2b;
text-align: center;
padding: 10px 20px;
cursor: default;
display: flex;
align-items: center;
font-size: 30px;
div {
display: flex;
flex-direction: column;
justify-content: flex-start;
text-align: left;
padding-left: 20px;
p:nth-child(1) {
font-weight: 600;
padding-bottom: 20px;
}
}
&:last-child:hover {
background: #fff;
cursor: pointer;
}
}
p {
font-size: 15px;
// line-height: 25px;
}
}
}
}
.float_box:hover .float_content {
display: block;
}
.float_content {
background-color: red;
}
.triangle_left {
&::after {
content: "";
width: 0;
height: 0;
display: inline-block;
border-left: 10px solid rgb(255, 255, 255);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid transparent;
position: absolute;
bottom: 10px;
right: -20px;
}
}
.triangle_right {
&::after {
content: "";
width: 0;
height: 0;
display: inline-block;
border-right: 10px solid rgb(255, 255, 255);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid transparent;
position: absolute;
bottom: 15px;
left: -22px;
}
}
// 右上
.triangle_top {
&::after {
content: "";
width: 0;
height: 0;
display: inline-block;
border-right: 10px solid transparent;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid #fff;
position: absolute;
bottom: 215px;
right: -20px;
}
}
// 左下
.triangle_bottom {
&::after {
content: "";
width: 0;
height: 0;
display: inline-block;
border-right: 10px solid rgb(255, 255, 255);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid transparent;
position: absolute;
bottom: 10px;
left: -20px;
}
}
// 左上
.triangle_btn {
&::after {
content: "";
width: 0;
height: 0;
display: inline-block;
border-right: 10px solid rgb(255, 255, 255);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid transparent;
position: absolute;
bottom: 215px;
left: -20px;
}
}
.right {
position: absolute;
bottom: 10px;
left: 60px;
}
.left {
position: absolute;
right: 60px;
border: 1px solid red;
bottom: 10px;
}
.top{
position: absolute;
right: 58px;
top: 13px;
}
.bottom{
position: absolute;
left: 60px;
bottom: 10px;
}
.btn{
position: absolute;
left: 60px;
bottom: -205px;
}
.hover_style:hover {
background-color: #ccc !important;
}
</style>