JS实现悬浮球只在一侧滑动并且是横屏状态下


Posted in Javascript onAugust 19, 2020

公司有一个新的需求 是需要悬浮球在一侧上下滑动 其实是很简单的 而且网上都有各种案例,但是 偏偏是横屏状态下 ,而且不是手机横屏 是用css强制旋转屏幕90度之后的横屏,所以就会出现坐标系的紊乱,然后我这个功能一开始做成的效果就是触摸上下滑动的时候 ,悬浮球是左右走(目前的这个图片的上下左右),当时非常的苦恼,接下来贴上我的代码,大家可以参考,有问题可以评论指出,谢谢!我先把我的基本布局拿过来,用的js是flexible.js 写的移动端的布局;

因为代码是有一阵子了 我也是从网上找的相关的正常悬浮球的移动的案例 之后再研究的横屏下的悬浮球移动;如涉及侵权,请谅解 或者指出 我会标明出处;感谢配合;

JS实现悬浮球只在一侧滑动并且是横屏状态下

下面的是html

图片那里大家可以自行更换

<body>
 <div id="example">
 <!-- 侧边的悬浮球 -->
 <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;
 /* 这是分割线 以下是为了屏幕旋转成横屏 仅供参考 */
 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]

JS实现悬浮球只在一侧滑动并且是横屏状态下JS实现悬浮球只在一侧滑动并且是横屏状态下

这个是大盒子的间距; offsetLeft 和 offsetTop 也不是视觉中的left和top

var bigBox_l = bigBox.offsetLeft;
var bigBox_t = bigBox.offsetTop ;

此时的大盒子的 offsetTop 为0 我就不在图中标出来了;大家应该明白 就是图中的右边距离;

JS实现悬浮球只在一侧滑动并且是横屏状态下

手机按下事件 这里就不多说了 基本上就是按下(touchstart) 移动(touchmove) 抬起 (touchend)

整体的逻辑 就是按下的时候 记录一下鼠标在小盒子里面的位置

以下就是关键,弄不好鼠标的位置就记录错了,我也是反反复复的想 才想明白;

我会用图向大家解说

disX = bigbox_w - ev.touches[0].pageX - smallBox.offsetTop;
 disY = ev.touches[0].pageY - bigBox_l;

JS实现悬浮球只在一侧滑动并且是横屏状态下JS实现悬浮球只在一侧滑动并且是横屏状态下

鼠标按下的值已经记录完毕 然后就是鼠标移动的时候 小球也要跟着动

var moveX = bigbox_w - e.touches[0].pageX - disX;
 var moveY = e.touches[0].pageY - disY;

JS实现悬浮球只在一侧滑动并且是横屏状态下JS实现悬浮球只在一侧滑动并且是横屏状态下

最后就是赋值

当然了 临界值的话 比较好判断 这里就不多说了;

smallBox.style.top = moveX + 'px';
 smallBox.style.left = moveY + 'px';

这里需要注意的是 小盒子的top值 其实是你最后算出来的moveX 值;left值 就是moveY 值;写了好久了 自己的能力有限 如果有更好的或者可以改进的方式 随时等待大家的评论来指点,谢谢大家;

到此这篇关于JS实现悬浮球只在一侧滑动 并且是横屏状态下的文章就介绍到这了,更多相关js悬浮球滑动内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript中的Window窗口对象
Jan 16 Javascript
js对象的构造和继承实现代码
Dec 05 Javascript
jQuery源码解读之removeAttr()方法分析
Feb 20 Javascript
郁闷!ionic中获取ng-model绑定的值为undefined如何解决
Aug 27 Javascript
详解jQuery的Cookie插件
Nov 23 Javascript
JS简单实现表格排序功能示例
Dec 20 Javascript
jQuery实现最简单实用的分秒倒计时
Feb 05 Javascript
this.$toast() 了解一下?
Apr 18 Javascript
用webpack4开发小程序的实现方法
Jun 04 Javascript
Vue解析剪切板图片并实现发送功能
Feb 04 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
Jan 05 Vue.js
React如何创建组件
Jun 27 Javascript
Javascript前端下载后台传来的文件流代码实例
Aug 18 #Javascript
Vue-cli assets SubDirectory及PublicPath区别详解
Aug 18 #Javascript
JavaScript语句错误throw、try及catch实例解析
Aug 18 #Javascript
JavaScript中交换值的10种方法总结
Aug 18 #Javascript
js+css3实现炫酷时钟
Aug 18 #Javascript
纯js+css实现在线时钟
Aug 18 #Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
Aug 18 #Javascript
You might like
测试PHP连接MYSQL成功与否的代码
2013/08/16 PHP
PHP+ajaxfileupload+jcrop插件完美实现头像上传剪裁
2014/06/09 PHP
一个经典的PHP文件上传类分享
2014/11/18 PHP
PHP中单例模式与工厂模式详解
2017/02/17 PHP
SCP远程VPS快速搬家和WDCP升级php5.3安装memcached和eaccelerator教程
2017/07/27 PHP
JavaScript 注册事件代码
2011/01/27 Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
2011/08/23 Javascript
js判断样式className同时增加class或删除class
2013/01/30 Javascript
使用JQuery实现Ctrl+Enter提交表单的方法
2015/10/22 Javascript
javascript运动框架用法实例分析(实现放大与缩小效果)
2016/01/08 Javascript
卸载安装Node.js与npm过程详解
2016/08/15 Javascript
VueJs与ReactJS和AngularJS的异同点
2016/12/12 Javascript
Thinkjs3新手入门之如何使用静态资源目录
2017/12/06 Javascript
详解vue-cli 本地开发mock数据使用方法
2018/05/29 Javascript
vue.js指令v-for使用以及下标索引的获取
2019/01/31 Javascript
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
layer关闭当前窗口页面以及确认取消按钮的方法
2019/09/09 Javascript
基于 Vue 的 Electron 项目搭建过程图文详解
2020/07/22 Javascript
springboot+vue实现文件上传下载
2020/11/17 Vue.js
[47:43]Alliance vs KG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
使用Python脚本操作MongoDB的教程
2015/04/16 Python
python 调用HBase的简单实例
2016/12/18 Python
Python使用QQ邮箱发送Email的方法实例
2017/02/09 Python
Python网络编程详解
2017/10/31 Python
使用Python的turtle模块画图的方法
2017/11/15 Python
Python操作mysql数据库实现增删查改功能的方法
2018/01/15 Python
Python实现的读取/更改/写入xml文件操作示例
2018/08/30 Python
如何使用Python自动控制windows桌面
2019/07/11 Python
Python中模块(Module)和包(Package)的区别详解
2019/08/07 Python
使用OpenCV实现仿射变换—旋转功能
2019/08/29 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
2019/08/30 Python
大学生毕业自我鉴定范文
2013/09/19 职场文书
党的群众路线对照检查材料(个人)
2014/09/24 职场文书
HTML+css盒子模型案例(圆,半圆等)“border-radius” 简单易上手
2021/05/10 HTML / CSS
MySQL 可扩展设计的基本原则
2021/05/14 MySQL
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python