Vue實現(xiàn)仿iPhone懸浮球的示例代碼
懸浮球插件簡單的效果圖:
很遺憾,沒找到太好的視頻轉(zhuǎn)gif的軟件,壓縮出來的大小超過了限制,就不放圖了
可以參考其他人的圖,效果一致:
簡單實用案例:
<!-- 給定一個初始位置position,插槽中填寫想滑動的部分 --> <xuanfuqiu :position="position"> <d-add-button @click="addPigFarm" add-item="豬場"></d-add-button> </xuanfuqiu>
原理示意圖
請結(jié)合代碼注釋來理解
懸浮球插件代碼如下:
<template> <div> <div class="xuanfu" id="moveDiv" :style="position" @mousedown="down" @touchstart="down" @mousemove="move" @touchmove="move" @mouseup="end" @touchend="end"> <slot></slot> </div> </div> </template> <script> export default { name: "", components: {}, props: { // 通過position來設(shè)置初始定位 position: { type: Object, default: function() { return { top: "32.25rem", left: "18.34375rem" } } }, // 通過fixed來禁用自由移動 fixed: { type: Boolean, default: false } }, data() { return { flags: false, positionTemp: { x: 0, y: 0 }, // 記錄手指點擊的位置 nx: '', ny: '', dx: '', dy: '', xPum: '', yPum: '', } }, watch: {}, computed: {}, methods: { // 實現(xiàn)移動端拖拽 down(){ if (this.fixed) { return } this.flags = true; var touch; // 該if判斷是用touch還是mouse來移動 if (event.touches) { touch = event.touches[0]; } else { touch = event; } this.positionTemp.x = touch.clientX; // 手指點擊后的位置 this.positionTemp.y = touch.clientY; this.dx = moveDiv.offsetLeft; // 移動的div元素的位置 this.dy = moveDiv.offsetTop; // console.log("moveDiv.offsetLeft", moveDiv.offsetLeft) // console.log("touch.clientX", touch.clientX) }, move(){ if(this.flags) { var touch ; if(event.touches){ touch = event.touches[0]; }else { touch = event; } this.nx = touch.clientX - this.positionTemp.x; // 手指移動的變化量 this.ny = touch.clientY - this.positionTemp.y; this.xPum = this.dx + this.nx; // 移動后,div元素的位置 this.yPum = this.dy + this.ny; let windowWidth = document.documentElement.clientWidth let windowHeight = document.documentElement.clientHeight // console.log("window.clientWidth", windowWidth) // console.log(this.xPum) // console.log(" moveDiv.clientWidth", moveDiv.clientWidth) if (this.xPum > 0 && (this.xPum + moveDiv.clientWidth < windowWidth)) { // movediv的左右邊,未出界 moveDiv.style.left = this.xPum + "px"; } else if (this.xPum <= 0) { // 左邊出界,則左邊緣貼邊 moveDiv.style.left = 0 + "px"; } else if (this.xPum + moveDiv.clientWidth >= windowWidth) { // 右邊緣出界 moveDiv.style.left = (windowWidth - moveDiv.clientWidth) + "px"; // console.log("dx", windowWidth - moveDiv.clientWidth) } // 上下未出界 if (this.yPum > 0 && (this.yPum + moveDiv.clientHeight < windowHeight)) { moveDiv.style.top = this.yPum +"px"; } else if (this.yPum <= 0) { // 上邊緣出界 moveDiv.style.top = 0 + "px" } else if (this.yPum + moveDiv.clientHeight >= windowHeight) { // 下邊緣 // console.log("windowHeight:", windowHeight) // console.log("moveDiv.clientHeight:", moveDiv.clientHeight) // console.log(this.yPum + moveDiv.clientHeight) moveDiv.style.top = windowHeight - moveDiv.clientHeight + "px" } // 阻止頁面的滑動默認(rèn)事件,為了只讓懸浮球滑動,其他部分不滑動;如果碰到滑動問題,1.2 請注意是否獲取到 touchmove, 系統(tǒng)默認(rèn)passive: true,無法使用preventDefault // document.addEventListener("touchmove", function(){ // event.preventDefault(); // }, { passive: false }); // document.addEventListener("mousemove", function(){ // event.preventDefault(); // }, { passive: false }); document.addEventListener("touchmove", this.preventDefault, { passive: false }) document.addEventListener("mousemove", this.preventDefault, { passive: false }) } }, //鼠標(biāo)釋放時候的函數(shù),鼠標(biāo)釋放,移除之前添加的偵聽事件,將passive設(shè)置為true,不然背景會滑動不了 end(){ this.flags = false // 注意事項,在添加和刪除監(jiān)聽事件時,其function必須是同名的函數(shù),不能為匿名函數(shù)。 document.removeEventListener('touchmove',this.preventDefault, false) document.removeEventListener('mousemove',this.preventDefault, false) // 下面兩句是保證在移除監(jiān)聽事件后,除了懸浮球的部分還能夠滑動,如果不添加,則無法滑動 document.addEventListener("touchmove", function(e) { window.event.returnValue = true }) document.addEventListener("mousemove", function(e) { window.event.returnValue = true }) }, preventDefault(e) { e.preventDefault() } }, created() {}, mounted() {} } </script> <style lang="scss" scoped> .xuanfu { /* 如果碰到滑動問題,1.3 請檢查 z-index。z-index需比web大一級*/ z-index: 999; position: fixed; // 這里的定位方式有待考量,fixed的話存在未知設(shè)置不合理,跑出屏幕不顯示的問題 } </style>
到此這篇關(guān)于Vue實現(xiàn)仿iPhone懸浮球的示例代碼的文章就介紹到這了,更多相關(guān)Vue 懸浮球內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue版本vue2.9.6升級到vue3.0的詳細(xì)步驟
vue版本升級相信大家應(yīng)該都遇到過,下面這篇文章主要給大家介紹了關(guān)于Vue版本vue2.9.6升級到vue3.0的詳細(xì)步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Vue中使用create-keyframe-animation與動畫鉤子完成復(fù)雜動畫
這篇文章主要介紹了Vue中使用create-keyframe-animation與動畫鉤子完成復(fù)雜動畫,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04解決vue-cli創(chuàng)建項目的loader問題
下面小編就為大家分享一篇解決vue-cli創(chuàng)建項目的loader問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看看吧2018-03-03vue主動刷新頁面及列表數(shù)據(jù)刪除后的刷新實例
今天小編就為大家分享一篇vue主動刷新頁面及列表數(shù)據(jù)刪除后的刷新實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09