公司有一個新的需求 是需要懸浮球在一側上下滑動 其實是很簡單的 而且網上都有各種案例,但是 偏偏是橫屏狀態下 ,而且不是手機橫屏 是用css強制旋轉屏幕90度之后的橫屏,所以就會出現坐標系的紊亂,然后我這個功能一開始做成的效果就是觸摸上下滑動的時候 ,懸浮球是左右走(目前的這個圖片的上下左右),當時非常的苦惱,接下來貼上我的代碼,大家可以參考,有問題可以評論指出,謝謝!我先把我的基本布局拿過來,用的js是flexible.js 寫的移動端的布局;
因為代碼是有一陣子了 我也是從網上找的相關的正常懸浮球的移動的案例 之后再研究的橫屏下的懸浮球移動;如涉及侵權,請諒解 或者指出 我會標明出處;感謝配合;
下面的是html
圖片那里大家可以自行更換
<body> <div id="example"> <!-- 側邊的懸浮球 --> <div class="sideDown"> <ul class="smallDown"> <img class="suspBall" src="./images/sideDownLogo.png" <li class="comeOut"> <p class="Take_back"><img src="./images/putAway.png" <p class="save_game"> <img src="./images/saveLogo.png" <i>保存</i> </p> <p class="down_game"> <img src="./images/downLogo.png" <i>下載</i> </p> </li> </ul> </div> </div> </body>
下面的是css 因為我當時寫這個的時候是依賴于一個云項目中的SDK 自帶的樣式 它的樣式就是這么強制橫屏的 所以我當時為了測試,就自己先寫在了自己的樣式里面 僅供參考 如有更好的 大家可以盡可能的提出!
#example { width: 100%; height: 100%; position: relative; /* 這是分割線 以下是為了屏幕旋轉成橫屏 僅供參考 */ width: 667px; height: 375px; left: -146px; top: 146px; -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); -moz-transform-origin: center center; -webkit-transform-origin: center center; -o-transform-origin: center center; -ms-transform-origin: center center; transform-origin: center center } /* 側邊的懸浮球 */ .sideDown { width: 1rem; height: 100%; position: absolute; z-index: 444; right: 0; display: block; } .sideDown ul { width: 1rem; height: 1rem; display: flex; align-items: center; position: absolute; top: 20px; right: 0; opacity: 1; } .sideDown ul img.suspBall { display: inline-block; width: 1rem; height: 1rem; z-index: 333; } .sideDown li { position: absolute; z-index: 222; right: 0.15rem; width: 3.3rem; height: 0.60rem; background: rgba(255, 230, 0, 1); border-radius: 0.35rem; opacity: 0.9; display: flex; align-items: center; } .sideDown li p { height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; margin-left: 0.5rem; } .sideDown li p img { display: inline-block; width: 0.29rem; height: 0.29rem; } .sideDown li p:first-child { width: 0.2rem; height: 0.2rem; margin-left: 0.16rem; } .sideDown li p:first-child img { display: inline-block; width: 0.2rem; height: 0.2rem; } .sideDown li p:first-child img { display: inline-block; width: 0.2rem; height: 0.2rem; } .sideDown li p i { display: inline-block; font-size: 0.17rem; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: rgba(51, 51, 51, 1); }
以下是重點 js代碼
<script> window.onload = function () { var flag = 0; //標記是拖曳還是點擊 var disX, disY; var targetW = 0;//剛進來的時候懸浮球左邊的寬度是正常的; // 獲取元素 var bigBox = document.querySelector(".sideDown"); var sBox = document.querySelector(".smallDown"); var sBoxImg = document.querySelector(".suspBall"); // console.log("獲取元素", bigBox, sBox) // 獲取大盒子的大小 var bigbox_w = bigBox.offsetHeight; var bigbox_h = bigBox.offsetWidth; // console.log("獲取大盒子的大小", bigbox_w, bigbox_h) // 獲取小盒子的大小 var sbox_w = sBox.offsetHeight; var sbox_h = sBox.offsetWidth ; // console.log("獲取小盒子的大小", sbox_w, sbox_h) // 獲取大盒子的間距 var bigBox_l = bigBox.offsetLeft; var bigBox_t = bigBox.offsetTop ; // console.log("獲取大盒子的間距", bigBox_l, bigBox_t) // 小盒子鼠標按下才觸發事件 sBoxImg.addEventListener("touchstart", function (ev) { flag = 0; ev = ev || window.event; ev.preventDefault();//阻止觸摸時頁面的滾動,縮放 // 獲取鼠標在盒子中的位置 // 觸點位置減去小盒子的間距就是鼠標在小盒子中的位置 disX = bigbox_w - ev.touches[0].pageX - sBox.offsetTop; disY = ev.touches[0].pageY - bigBox_l; console.log("獲取觸點位置", ev.touches[0].pageY, ev.touches[0].pageX) console.log("小盒子的左和上間距", sBox.offsetLeft, sBox.offsetTop) console.log("獲取鼠標在盒子中的位置", disX, disY) }) sBoxImg.addEventListener("touchmove", function (e) { flag = 1; e = e || window.event; // 用這次獲取到的鼠標的位置減去上次鼠標在小盒子的位置就是小盒子的左和上間距 var moveX = bigbox_w - e.touches[0].pageX - disX; var moveY = e.touches[0].pageY - disY; // console.log("移動的時候~~獲取觸點位置", e.touches[0].pageX, e.touches[0].pageY) // console.log("獲取上次鼠標在盒子中的位置", disX, disY) // console.log("小盒子的左和上間距", moveX, moveY) if (moveX < 0) { moveX = 0; } if (moveY < 0) { moveY = 0; } if (moveX > bigbox_w - sbox_w) { moveX = bigbox_w - sbox_w; } if (moveY > bigbox_h - sbox_h) { moveY = bigbox_h - sbox_h; } sBox.style.top = moveX + "px"; sBox.style.left = moveY + "px"; }) sBoxImg.addEventListener("touchend", function (e) { // console.log("結束") //判斷滑動方向 if (flag === 0) {//點擊 // console.log("點擊了"); if (targetW == 0) { console.log("收回去了", targetW) $(".comeOut").animate({ width: "0.3rem", opacity: "0.5", }, "slow", function () { targetW = 1; //改變懸浮球左邊大小的時候 改變這個值 以便于后面的判斷; }) } if (targetW == 1) { console.log("放出來了", targetW) $(".comeOut").animate({ width: "3.3rem", opacity: "0.9", }, "slow", function () { targetW = 0; }) } } }); $(".Take_back").click(function (event) { console.log("點擊箭頭", targetW) $(".comeOut").animate({ width: "0.3rem", opacity: "0.5", }, "slow", function () { targetW = 1; //改變懸浮球左邊大小的時候 改變這個值 以便于后面的判斷; }) event.stopPropagation() }); } </script>
下面進行詳細的解說:
var bigbox_w = bigBox.offsetHeight; var bigbox_h = bigBox.offsetWidth;
這兩句 按正常的豎屏的話應該是
var bigbox_w = bigBox.offsetWidth; var bigbox_h = bigBox.offsetHeight; offsetWidth 顯示的是盒子正常的寬 (也就是你css里面寫的寬) offsetHeight 顯示的是盒子正常的高 (也就是你css里面寫的高)
但是 由于橫屏 你的視覺中看到的就是一下左圖中 寬 高
這就是需要把 offsetWidth 和 offsetHeight 換一下 才是右圖中打印出來的寬高 才是視覺中的寬高;
同理 小盒子的大小(16,17行)也需要換一下,盡管小盒子是一個正方形的 ;[/code]
這個是大盒子的間距; offsetLeft 和 offsetTop 也不是視覺中的left和top
var bigBox_l = bigBox.offsetLeft; var bigBox_t = bigBox.offsetTop ;
此時的大盒子的 offsetTop 為0 我就不在圖中標出來了;大家應該明白 就是圖中的右邊距離;
手機按下事件 這里就不多說了 基本上就是按下(touchstart) 移動(touchmove) 抬起 (touchend)
整體的邏輯 就是按下的時候 記錄一下鼠標在小盒子里面的位置
以下就是關鍵,弄不好鼠標的位置就記錄錯了,我也是反反復復的想 才想明白;
我會用圖向大家解說
disX = bigbox_w - ev.touches[0].pageX - smallBox.offsetTop; disY = ev.touches[0].pageY - bigBox_l;
鼠標按下的值已經記錄完畢 然后就是鼠標移動的時候 小球也要跟著動
var moveX = bigbox_w - e.touches[0].pageX - disX; var moveY = e.touches[0].pageY - disY;
最后就是賦值
當然了 臨界值的話 比較好判斷 這里就不多說了;
smallBox.style.top = moveX + "px"; smallBox.style.left = moveY + "px";
這里需要注意的是 小盒子的top值 其實是你最后算出來的moveX 值;left值 就是moveY 值;寫了好久了 自己的能力有限 如果有更好的或者可以改進的方式 隨時等待大家的評論來指點,謝謝大家;
到此這篇關于JS實現懸浮球只在一側滑動 并且是橫屏狀態下的文章就介紹到這了,更多相關js懸浮球滑動內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/ting0410/p/13524906.html