vue實(shí)現(xiàn)帶自動(dòng)吸附功能的懸浮球
本文實(shí)例為大家分享了vue實(shí)現(xiàn)帶自動(dòng)吸附功能的懸浮球,供大家參考,具體內(nèi)容如下
封裝的組件代碼,可以引到頁(yè)面直接使用
<template> ? <div ? ? ref="floatDrag" ? ? class="float-position" ? ? :style="{ left: left + 'px', top: top + 'px', zIndex: zIndex }" ? ? @touchmove.prevent ? ? @mousemove.prevent ? ? @mousedown="mouseDown" ? ? @mouseup="mouseUp" ? > ? ? <svg ? ? ? t="1630029318602" ? ? ? class="icon" ? ? ? viewBox="0 0 1024 1024" ? ? ? version="1.1" ? ? ? xmlns="http://www.w3.org/2000/svg" ? ? ? p-id="1244" ? ? ? width="200" ? ? ? height="200" ? ? > ? ? ? <path ? ? ? ? d="M554.376075 850.102995l0.208185 87.874926 170.711774-0.14573v85.355887l-209.038649 0.187367c-1.39484 0.124911-2.727225 0.41637-4.163702 0.41637s-2.706406-0.291459-4.163702-0.41637l-208.997011 0.187366v-85.230975l170.33704-0.14573-0.208185-88.041474A383.643483 383.643483 0 0 1 128.200378 469.061825h84.772969a298.37087 298.37087 0 0 0 294.769268 297.704678c1.290748-0.124911 2.539858-0.395552 3.872243-0.395551s2.498221 0.270641 3.76815 0.374733a298.350052 298.350052 0 0 0 294.60272-297.704678h85.751438a383.664302 383.664302 0 0 1-341.361091 381.061988z m-42.240755-168.047005A213.160713 213.160713 0 0 1 298.93297 468.936914h0.458007l-0.374733-255.65129a213.160713 213.160713 0 0 1 426.300608-1.936121c0 0.374733 0.124911 0.728648 0.124911 1.124199l0.374733 256.463212a42.782036 42.782036 0 0 1-0.791103 7.890215 213.035802 213.035802 0 0 1-212.890073 205.228861z m128.32529-213.223168l-0.374734-255.65129h-0.333096a127.721552 127.721552 0 0 0-255.422286 0h-0.166548l0.374733 255.65129v1.061744a127.659097 127.659097 0 0 0 255.318194-0.957652h0.624555a0.895196 0.895196 0 0 0-0.124911-0.104092z m-129.366215-42.532214h2.081851H510.990302z" ? ? ? ? fill="#fff" ? ? ? ? p-id="1245" ? ? ? ></path> ? ? </svg> ? </div> </template> <script> export default { ? name: "DragBall", ? props: { ? ? distanceRight: { ? ? ? type: Number, ? ? ? default: 0 ? ? }, ? ? distanceBottom: { ? ? ? type: Number, ? ? ? default: 100 ? ? }, ? ? isScrollHidden: { ? ? ? type: Boolean, ? ? ? default: false ? ? }, ? ? isCanDraggable: { ? ? ? type: Boolean, ? ? ? default: true ? ? }, ? ? zIndex: { ? ? ? type: Number, ? ? ? default: 50 ? ? }, ? ? value: { ? ? ? type: String, ? ? ? default: "懸浮球!" ? ? } ? }, ? //data 域 ? data() { ? ? return { ? ? ? clientWidth: null, ? ? ? clientHeight: null, ? ? ? left: 0, ? ? ? top: 0, ? ? ? timer: null, ? ? ? currentTop: 0, ? ? ? mousedownX: 0, ? ? ? mousedownY: 0 ? ? }; ? }, ? created() { ? ? this.clientWidth = document.documentElement.clientWidth; ? ? this.clientHeight = document.documentElement.clientHeight; ? }, ? mounted() { ? ? this.isCanDraggable && ? ? ? this.$nextTick(() => { ? ? ? ? this.floatDrag = this.$refs.floatDrag; ? ? ? ? // 獲取元素位置屬性 ? ? ? ? this.floatDragDom = this.floatDrag.getBoundingClientRect(); ? ? ? ? // 設(shè)置初始位置 ? ? ? ? this.left = ? ? ? ? ? this.clientWidth - this.floatDragDom.width - this.distanceRight; ? ? ? ? this.top = ? ? ? ? ? this.clientHeight - this.floatDragDom.height - this.distanceBottom; ? ? ? ? this.initDraggable(); ? ? ? }); ? ? this.isScrollHidden && window.addEventListener("scroll", this.handleScroll); ? ? window.addEventListener("resize", this.handleResize); ? }, ? methods: { ? ? /** ? ? ?* 設(shè)置滾動(dòng)監(jiān)聽(tīng) ? ? ?* 設(shè)置滾動(dòng)時(shí)隱藏懸浮按鈕,停止時(shí)顯示 ? ? ?*/ ? ? handleScroll() { ? ? ? this.timer && clearTimeout(this.timer); ? ? ? this.timer = setTimeout(() => { ? ? ? ? this.handleScrollEnd(); ? ? ? }, 200); ? ? ? this.currentTop = ? ? ? ? document.documentElement.scrollTop || document.body.scrollTop; ? ? ? if (this.left > this.clientWidth / 2) { ? ? ? ? // 判斷元素位置再左側(cè)還是右側(cè) ? ? ? ? this.left = this.clientWidth + this.floatDragDom.width; ? ? ? } else { ? ? ? ? this.left = -this.floatDragDom.width; ? ? ? } ? ? }, ? ? /** ? ? ?* 滾動(dòng)結(jié)束 ? ? ?*/ ? ? handleScrollEnd() { ? ? ? let scrollTop = ? ? ? ? document.documentElement.scrollTop || document.body.scrollTop; ? ? ? if (scrollTop === this.currentTop) { ? ? ? ? console.log(this.left); ? ? ? ? if (this.left > this.clientWidth / 2) { ? ? ? ? ? // 判斷元素位置再左側(cè)還是右側(cè) ? ? ? ? ? this.left = this.clientWidth - this.floatDragDom.width; ? ? ? ? } else { ? ? ? ? ? this.left = 0; ? ? ? ? } ? ? ? ? clearTimeout(this.timer); ? ? ? } ? ? }, ? ? /** ? ? ?* 窗口resize監(jiān)聽(tīng) ? ? ?*/ ? ? handleResize() { ? ? ? this.clientWidth = document.documentElement.clientWidth; ? ? ? this.clientHeight = document.documentElement.clientHeight; ? ? ? this.checkDraggablePosition(); ? ? }, ? ? /** ? ? ?* 初始化draggable ? ? ?*/ ? ? initDraggable() { ? ? ? this.floatDrag.addEventListener("touchstart", this.toucheStart); ? ? ? this.floatDrag.addEventListener("touchmove", e => this.touchMove(e)); ? ? ? this.floatDrag.addEventListener("touchend", this.touchEnd); ? ? }, ? ? mouseDown(e) { ? ? ? const event = e || window.event; ? ? ? this.mousedownX = event.screenX; ? ? ? this.mousedownY = event.screenY; ? ? ? const that = this; ? ? ? let floatDragWidth = this.floatDragDom.width / 2; ? ? ? let floatDragHeight = this.floatDragDom.height / 2; ? ? ? if (event.preventDefault) { ? ? ? ? event.preventDefault(); ? ? ? } ? ? ? this.canClick = false; ? ? ? this.floatDrag.style.transition = "none"; ? ? ? document.onmousemove = function(e) { ? ? ? ? var event = e || window.event; ? ? ? ? that.left = event.clientX - floatDragWidth; ? ? ? ? that.top = event.clientY - floatDragHeight; ? ? ? ? if (that.left < 0) that.left = 0; ? ? ? ? if (that.top < 0) that.top = 0; ? ? ? ? if (that.left >= that.clientWidth - floatDragWidth * 2) { ? ? ? ? ? that.left = that.clientWidth - floatDragWidth * 2; ? ? ? ? } ? ? ? ? if (that.top >= that.clientHeight - floatDragHeight * 2) { ? ? ? ? ? that.top = that.clientHeight - floatDragHeight * 2; ? ? ? ? } ? ? ? }; ? ? }, ? ? mouseUp(e) { ? ? ? const event = e || window.event; ? ? ? //判斷只是單純的點(diǎn)擊,沒(méi)有拖拽 ? ? ? if ( ? ? ? ? this.mousedownY == event.screenY && ? ? ? ? this.mousedownX == event.screenX ? ? ? ) { ? ? ? ? this.$emit("handlepaly"); ? ? ? } ? ? ? document.onmousemove = null; ? ? ? this.checkDraggablePosition(); ? ? ? this.floatDrag.style.transition = "all 0.3s"; ? ? }, ? ? toucheStart() { ? ? ? this.canClick = false; ? ? ? this.floatDrag.style.transition = "none"; ? ? }, ? ? touchMove(e) { ? ? ? this.canClick = true; ? ? ? if (e.targetTouches.length === 1) { ? ? ? ? // 單指拖動(dòng) ? ? ? ? let touch = event.targetTouches[0]; ? ? ? ? this.left = touch.clientX - this.floatDragDom.width / 2; ? ? ? ? this.top = touch.clientY - this.floatDragDom.height / 2; ? ? ? } ? ? }, ? ? touchEnd() { ? ? ? if (!this.canClick) return; // 解決點(diǎn)擊事件和touch事件沖突的問(wèn)題 ? ? ? this.floatDrag.style.transition = "all 0.3s"; ? ? ? this.checkDraggablePosition(); ? ? }, ? ? /** ? ? ?* 判斷元素顯示位置 ? ? ?* 在窗口改變和move end時(shí)調(diào)用 ? ? ?*/ ? ? checkDraggablePosition() { ? ? ? if (this.left + this.floatDragDom.width / 2 >= this.clientWidth / 2) { ? ? ? ? // 判斷位置是往左往右滑動(dòng) ? ? ? ? this.left = this.clientWidth - this.floatDragDom.width; ? ? ? } else { ? ? ? ? this.left = 0; ? ? ? } ? ? ? if (this.top < 0) { ? ? ? ? // 判斷是否超出屏幕上沿 ? ? ? ? this.top = 0; ? ? ? } ? ? ? if (this.top + this.floatDragDom.height >= this.clientHeight) { ? ? ? ? // 判斷是否超出屏幕下沿 ? ? ? ? this.top = this.clientHeight - this.floatDragDom.height; ? ? ? } ? ? } ? }, ? beforeDestroy() { ? ? window.removeEventListener("scroll", this.handleScroll); ? ? window.removeEventListener("resize", this.handleResize); ? } }; </script> <style> html, body { ? overflow: hidden; } </style> <style scoped lang="less"> .float-position { ? position: absolute; ? z-index: 10003; ? right: 0; ? top: 70%; ? width: 3.6em; ? height: 3.6em; ? background: deepskyblue; ? border-radius: 50%; ? overflow: hidden; ? box-shadow: 0px 0px 10px 2px skyblue; ? display: flex; ? align-items: center; ? justify-content: center; ? padding: 0.8em; ? user-select: none; } .cart { ? border-radius: 50%; ? width: 5em; ? height: 5em; ? display: flex; ? align-items: center; ? justify-content: center; } .header-notice { ? display: inline-block; ? transition: all 0.3s; ? span { ? ? vertical-align: initial; ? } ? .notice-badge { ? ? color: inherit; ? ? .header-notice-icon { ? ? ? font-size: 16px; ? ? ? padding: 4px; ? ? } ? } } .drag-ball .drag-content { ? overflow-wrap: break-word; ? font-size: 14px; ? color: #fff; ? letter-spacing: 2px; } </style>
頁(yè)面中使用:
<template> ? <div> ? ? <drag @handlepaly="handleaudioplay" style="cursor:pointer"></drag> ? </div> </template> <script> import drag from "./dragbase"; export default { ? components: { drag }, ? methods: { ? ? handleaudioplay() { ? ? ? ? console.log(123); ? ? } ? } }; </script>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue項(xiàng)目服務(wù)器部署刷新頁(yè)面404問(wèn)題及解決
這篇文章主要介紹了Vue項(xiàng)目服務(wù)器部署刷新頁(yè)面404問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Vue2.0/3.0雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理詳解
這篇文章主要給大家介紹了關(guān)于Vue2.0/3.0雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04VUE實(shí)現(xiàn)強(qiáng)制渲染,強(qiáng)制更新
今天小編就為大家分享一篇VUE實(shí)現(xiàn)強(qiáng)制渲染,強(qiáng)制更新,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10解決vue路由組件vue-router實(shí)例被復(fù)用問(wèn)題
這篇文章介紹了解決vue路由組件vue-router實(shí)例被復(fù)用的問(wèn)題,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06el-table?表格分頁(yè)序號(hào)問(wèn)題小結(jié)
這篇文章主要介紹了el-table?表格分頁(yè)序號(hào)問(wèn)題小結(jié),本文通過(guò)實(shí)例代碼圖文效果展示給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-04-04vue組件庫(kù)的在線主題編輯器的實(shí)現(xiàn)思路
這篇文章主要介紹了vue組件庫(kù)的在線主題編輯器的實(shí)現(xiàn)思路,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04