vue實(shí)現(xiàn)吸壁懸浮球
本文實(shí)例為大家分享了vue實(shí)現(xiàn)吸壁懸浮球的具體代碼,供大家參考,具體內(nèi)容如下
最近接到一個(gè)需求,需要一個(gè)客服懸浮按鈕,可以拖拽并吸壁到頁(yè)面周邊,我們一起看看吧
1.創(chuàng)建一個(gè)template,定義客服按鈕,自定義v-drag指令
<template> ? <div class="container"> ? ? <div ? ? ? class="btn" ? ? ? id="btn" ? ? ? :style="{ visibility: dialogVisible ? 'hidden' : 'visible' }" ? ? ? v-drag="{ set: openDialog }" ? ? ? draggable="false" ? ? > ? ? ? <img src="@/assets/images/cust-service.png" alt="" /> ? ? ? <span>聯(lián)<br />系<br />客<br />服</span> ? ? </div> ? ? <chat-dialog v-model="dialogVisible" @on-close="closeDialog"></chat-dialog> ? </div> </template>
2.drag指令主要監(jiān)聽el的onmousedown
、onmousemove
、onmouseup
事件,在onmouseup
事件通過偏移量判斷是點(diǎn)擊還是拖拽,如果是拖拽計(jì)算偏移量從而判斷吸附于哪個(gè)壁
<script> import chatDialog from "./chatDialog"; export default { ? components: { chatDialog }, ? data() { ? ? return { ? ? ? dialogVisible: false, ? ? }; ? }, ? mounted() { ? ? // 初始化按鈕位置 ? ? let clientW = document.documentElement.clientWidth; ? ? let clientH = document.documentElement.clientHeight; ? ? let div = document.getElementById("btn"); ? ? div.style.top = clientH / 2 + "px"; ? ? div.style.left = clientW - 80 + "px"; ? }, ? methods: { ? ? openDialog() { ? ? ? this.dialogVisible = true; ? ? }, ? ? closeDialog() { ? ? ? this.dialogVisible = false; ? ? }, ? }, ? directives: { ? ? drag(el, binding) { ? ? ? let oDiv = el; ? ? ? // 禁止選擇網(wǎng)頁(yè)上的文字 ? ? ? document.onselectstart = function () { ? ? ? ? return false; ? ? ? }; ? ? ? oDiv.onmousedown = function (e) { ? ? ? ? // 鼠標(biāo)按下,計(jì)算當(dāng)前元素距離可視區(qū)的距離 ? ? ? ? let disX = e.clientX - oDiv.offsetLeft; ? ? ? ? let disY = e.clientY - oDiv.offsetTop; ? ? ? ? // 記錄初始位置 ? ? ? ? let firstX = oDiv.offsetLeft; ? ? ? ? let firstY = oDiv.offsetTop; ? ? ? ? let l = oDiv.offsetLeft; ? ? ? ? let t = oDiv.offsetTop; ? ? ? ? document.onmousemove = function (e) { ? ? ? ? ? // 通過事件委托,計(jì)算移動(dòng)的距離 ? ? ? ? ? l = e.clientX - disX; ? ? ? ? ? t = e.clientY - disY; ? ? ? ? ? // 移動(dòng)當(dāng)前元素 ? ? ? ? ? oDiv.style.left = l + "px"; ? ? ? ? ? oDiv.style.top = t + "px"; ? ? ? ? }; ? ? ? ? document.onmouseup = function (e) { ? ? ? ? ? // 點(diǎn)擊事件 ? ? ? ? ? if (Math.abs(l - firstX) < 3 || Math.abs(t - firstY) < 3) { ? ? ? ? ? ? binding.value.set(true); ? ? ? ? ? } else { ? ? ? ? ? ? // 拖拽事件 ? ? ? ? ? ? let clientW = document.documentElement.clientWidth; ? ? ? ? ? ? let clientH = document.documentElement.clientHeight; ? ? ? ? ? ? // 判斷偏移量,并吸壁 ? ? ? ? ? ? // 垂直偏移量大于水平偏移量,左右吸壁,垂直控制范圍 ? ? ? ? ? ? if (Math.abs(t - firstY) > Math.abs(l - firstX)) { ? ? ? ? ? ? ? if (l > clientW / 2 - 80) { ? ? ? ? ? ? ? ? l = clientW - 80; ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? l = 80; ? ? ? ? ? ? ? } ? ? ? ? ? ? ? if (t < 40) t = 40; ? ? ? ? ? ? ? else if (t > clientH - 140) t = clientH - 140; ? ? ? ? ? ? } else { ? ? ? ? ? ? ? // 上下吸壁,水平控制范圍 ? ? ? ? ? ? ? if (t > clientH / 2 - 140) { ? ? ? ? ? ? ? ? t = clientH - 140; ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? t = 40; ? ? ? ? ? ? ? } ? ? ? ? ? ? ? if (l < 80) l = 80; ? ? ? ? ? ? ? else if (l > clientW - 80) l = clientW - 80; ? ? ? ? ? ? } ? ? ? ? ? ? oDiv.style.top = t + "px"; ? ? ? ? ? ? oDiv.style.left = l + "px"; ? ? ? ? ? } ? ? ? ? ? document.onmousemove = null; ? ? ? ? ? document.onmouseup = null; ? ? ? ? }; ? ? ? ? // return false不加的話可能導(dǎo)致黏連,就是拖到一個(gè)地方時(shí)div粘在鼠標(biāo)上不下來,相當(dāng)于onmouseup失效 ? ? ? ? return false; ? ? ? }; ? ? }, ? }, }; </script>
3.樣式設(shè)置z-index始終保持在頁(yè)面頂層,定義position定位
<style lang="scss" scoped> .container { ? .btn { ? ? z-index: 9999; ? ? position: fixed; ? ? width: 40px; ? ? height: 130px; ? ? overflow: hidden; ? ? background: linear-gradient(210deg, #f3f5f8, #ffffff); ? ? border: 2px solid #ffffff; ? ? box-shadow: 3px 5px 10px 0px rgba(0, 0, 0, 0.1); ? ? border-radius: 20px; ? ? text-align: center; ? ? img { ? ? ? margin: 5px 0; ? ? ? width: 30px; ? ? ? height: 30px; ? ? } ? ? span { ? ? ? font-size: 14px; ? ? ? color: #333333; ? ? ? cursor: pointer; ? ? ? font-family: PingFang SC; ? ? } ? } } </style>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
element-ui?table表格控件實(shí)現(xiàn)單選功能代碼實(shí)例
這篇文章主要給大家介紹了關(guān)于element-ui?table表格控件實(shí)現(xiàn)單選功能的相關(guān)資料,單選框是指在?Element?UI?的表格組件中,可以通過單選框來選擇一行數(shù)據(jù)。用戶只能選擇一行數(shù)據(jù),而不能同時(shí)選擇多行,需要的朋友可以參考下2023-09-09vue插槽slot的簡(jiǎn)單理解與用法實(shí)例分析
這篇文章主要介紹了vue插槽slot的簡(jiǎn)單理解與用法,結(jié)合實(shí)例形式分析了vue插槽slot的功能、原理、相關(guān)使用技巧與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03詳解基于Vue/React項(xiàng)目的移動(dòng)端適配方案
這篇文章主要介紹了詳解基于Vue/React項(xiàng)目的移動(dòng)端適配方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08vue引入子組件命名不規(guī)范錯(cuò)誤的解決方案
這篇文章主要介紹了vue引入子組件命名不規(guī)范錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04