JS實現(xiàn)懸浮球只在一側(cè)滑動并且是橫屏狀態(tài)下
公司有一個新的需求 是需要懸浮球在一側(cè)上下滑動 其實是很簡單的 而且網(wǎng)上都有各種案例,但是 偏偏是橫屏狀態(tài)下 ,而且不是手機橫屏 是用css強制旋轉(zhuǎn)屏幕90度之后的橫屏,所以就會出現(xiàn)坐標系的紊亂,然后我這個功能一開始做成的效果就是觸摸上下滑動的時候 ,懸浮球是左右走(目前的這個圖片的上下左右),當時非常的苦惱,接下來貼上我的代碼,大家可以參考,有問題可以評論指出,謝謝!我先把我的基本布局拿過來,用的js是flexible.js 寫的移動端的布局;
因為代碼是有一陣子了 我也是從網(wǎng)上找的相關(guān)的正常懸浮球的移動的案例 之后再研究的橫屏下的懸浮球移動;如涉及侵權(quán),請諒解 或者指出 我會標明出處;感謝配合;

下面的是html
圖片那里大家可以自行更換
<body> <div id="example"> <!-- 側(cè)邊的懸浮球 --> <div class="sideDown"> <ul class="smallDown"> <img class="suspBall" src="./images/sideDownLogo.png" alt=""> <li class="comeOut"> <p class="Take_back"><img src="./images/putAway.png" alt=""></p> <p class="save_game"> <img src="./images/saveLogo.png" alt=""> <i>保存</i> </p> <p class="down_game"> <img src="./images/downLogo.png" alt=""> <i>下載</i> </p> </li> </ul> </div> </div> </body>
下面的是css 因為我當時寫這個的時候是依賴于一個云項目中的SDK 自帶的樣式 它的樣式就是這么強制橫屏的 所以我當時為了測試,就自己先寫在了自己的樣式里面 僅供參考 如有更好的 大家可以盡可能的提出!
#example {
width: 100%;
height: 100%;
position: relative;
/* 這是分割線 以下是為了屏幕旋轉(zhuǎn)成橫屏 僅供參考 */
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
}
/* 側(cè)邊的懸浮球 */
.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)
// 小盒子鼠標按下才觸發(fā)事件
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('結(jié)束')
//判斷滑動方向
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;
這兩句 按正常的豎屏的話應(yīng)該是
var bigbox_w = bigBox.offsetWidth; var bigbox_h = bigBox.offsetHeight; offsetWidth 顯示的是盒子正常的寬 (也就是你css里面寫的寬) offsetHeight 顯示的是盒子正常的高 (也就是你css里面寫的高)
但是 由于橫屏 你的視覺中看到的就是一下左圖中 寬 高
這就是需要把 offsetWidth 和 offsetHeight 換一下 才是右圖中打印出來的寬高 才是視覺中的寬高;
同理 小盒子的大?。?6,17行)也需要換一下,盡管小盒子是一個正方形的 ;[/code]


這個是大盒子的間距; offsetLeft 和 offsetTop 也不是視覺中的left和top
var bigBox_l = bigBox.offsetLeft; var bigBox_t = bigBox.offsetTop ;
此時的大盒子的 offsetTop 為0 我就不在圖中標出來了;大家應(yīng)該明白 就是圖中的右邊距離;

手機按下事件 這里就不多說了 基本上就是按下(touchstart) 移動(touchmove) 抬起 (touchend)
整體的邏輯 就是按下的時候 記錄一下鼠標在小盒子里面的位置
以下就是關(guān)鍵,弄不好鼠標的位置就記錄錯了,我也是反反復(fù)復(fù)的想 才想明白;
我會用圖向大家解說
disX = bigbox_w - ev.touches[0].pageX - smallBox.offsetTop; disY = ev.touches[0].pageY - bigBox_l;


鼠標按下的值已經(jīng)記錄完畢 然后就是鼠標移動的時候 小球也要跟著動
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 值;寫了好久了 自己的能力有限 如果有更好的或者可以改進的方式 隨時等待大家的評論來指點,謝謝大家;
到此這篇關(guān)于JS實現(xiàn)懸浮球只在一側(cè)滑動 并且是橫屏狀態(tài)下的文章就介紹到這了,更多相關(guān)js懸浮球滑動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
layui表格數(shù)據(jù)復(fù)選框回顯設(shè)置方法
今天小編就為大家分享一篇layui表格數(shù)據(jù)復(fù)選框回顯設(shè)置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
JavaScript求一個數(shù)組中重復(fù)出現(xiàn)次數(shù)最多的元素及其下標位置示例
這篇文章主要介紹了JavaScript求一個數(shù)組中重復(fù)出現(xiàn)次數(shù)最多的元素及其下標位置,涉及javascript數(shù)組元素遍歷、判斷、正則過濾、追加等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07
細說JavaScript中的this指向與綁定規(guī)則
本文主要詳細介紹了JavaScript中的this指向與綁定規(guī)則,默認綁定,隱式綁定,顯示綁定,new綁定這四個規(guī)則,文中有相關(guān)的代碼示例供大家參考,感興趣的同學(xué)可以閱讀下2023-05-05
javascript設(shè)置金額樣式轉(zhuǎn)換保留兩位小數(shù)示例代碼
本文為大家介紹下javascript設(shè)置金額樣式即保留兩位小數(shù),下面有個不錯的教程,需要的朋友可以了解下2013-12-12

