当前位置: 首页 > news >正文

竖排主菜单鼠标滑动角度判断显示子分类

在较多电商类网站中,总会有竖排主类别菜单,鼠标滑动右侧显示分类下的详细类别,但因为是竖排分类,就可能会出现鼠标滑动时,只是想单纯的在露出的详细分类下,点击当前分类下的某个分类,但是因为鼠标滑动经过了其他分类,子分类菜单就被切换走了,只能鼠标平移至右侧,用户体验是极不好的。

比如下图在选择了 “女鞋/箱包/钟表/珠宝” 这个分类后, 鼠标正常从上方按箭头方向滑动到 “2017新品” 时, 在不做角度等辅助判断下,鼠标因为经过了 “美妆个护/宠物” 菜单后,右侧的分类就被切换走了(右侧显示了 “美妆个护/宠物” 的子分类),选右侧的东西完全靠鼠标平移,想想心也是塞的呢。

所以在这种情况下,我们需要对鼠标滑动的角度 和 停留时间进行判断,判断用户想要的操作是否是切换至其他分类,来进行切换。

 

从两个方面来判断切换最为稳妥,判断鼠标滑动角度 和 鼠标停留时长。

 

判断鼠标滑动角度

对于角度的计算考虑到各种数值约等于其实蛮复杂的,我觉得(什么正弦、余弦的,想想脑袋都大了),所以可以依靠斜率来判断角度,看是否进行切换。

记录鼠标移动的初识位置 A 最终位置B 的坐标,以初始位置为圆心做坐标轴,计算两点构成直线的斜率(Kab)进行下一步的操作。

 

在 起始位置 A 建立坐标轴,参照下图,对 最终位置 所在位置应当触发的情况进行逻辑梳理:

1.不需要进行菜单切换

  当鼠标最终位置在坐标系 1 , 2 区域, 默认菜单栏在主菜单右侧,虽然鼠标方向是向下或者向上进行了滑动,但是我们先默认用户是想点击右侧子菜单下方和上方的项目,所以暂不进行切换。

  当鼠标最终位置在坐标轴 X轴上时,因为左右区域都算是 当前主菜单栏目的子元素,所以也不进行切换。

2.需要进行菜单切换

  当鼠标最终位置在坐标系 3, 4 区域, 默认菜单栏在主菜单右侧,因为鼠标方向是向左下或者向左上进行了滑动,没有任何往右侧子菜单移动的意图,所以是进行切换。

  当鼠标最终位置在坐标轴 Y轴上时,垂直上下的移动表明用户就是想切换菜单,所以进行切换。

3.隐藏分类

  当鼠标在menu区域移除时,当前展示的子菜单应当隐藏不在显示。

 

 

 根据上面的逻辑梳理,我们编写以下核心逻辑代码:

 1 $(document).ready(function(){
 2     var site = []; //定义一个数组存储位置信息
 3     //监听鼠标移动获取位置信息
 4     $(document).mousemove(function(e){
 5          var e = e ? e:window.event;
 6          var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 
 7          var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 
 8          var x = e.pageX || e.clientX + scrollX; 
 9          var y = e.pageY || e.clientY + scrollY; 
10          //将获取的 位置信息以 坐标的形式,存储在 site 数组中
11          site.push({
12              x : x,
13              y : y
14          });
15          //只存储三个位置信息,超出删除第一个元素
16          if(site.length > 3){
17             site.shift();
18          }
19 
20 });
21 
22 //计算斜率 返回是否切换分类
23 var getSlope = function(set){
24     var len = site.length;
25     //只去数组中第一个和最后一个位置信息 做初识坐标和最终坐标
26     if(len > 2){
27         var siteArr = {
28                         x1 : site[0].x,
29                         y1 : site[0].y,
30                         x2 : site[len-1].x,
31                         y2 : site[len-1].y
32                       }
33         //如果鼠标进行了 竖向平移 或 横向平移 或 近乎于纵向平移 时正常进行切换,不进行接下来的判断
34         if(siteArr.x1 == siteArr.x2 || siteArr.y1 == siteArr.y2 || Math.abs(siteArr.x2 - siteArr.x1) <= 10){
35               return 0;
36         }
37         //我们以鼠标初始位置 坐标所在的垂直竖线为基线 ,若鼠标移动的方向在 基线左侧,而我们的子菜单在右侧,说明用户想要切换主菜单,所以也正常进行切换,不进行接下来的判断
38         if(siteArr.x2 < siteArr.x1){
39              return 0;
40         }
41         //set 为当前主菜单栏目项,我们判断鼠标的起始位置是否在主菜单栏目的外的左侧和栏目外的右侧,如果在说明用户刚移入主菜单,应进行切换,不进行接下来的判断
42         if(siteArr.x1 < set.left || siteArr.x1 > set.lx){
43              return 0;
44         }
45         //求斜率
46         var k = (siteArr.y2-siteArr.y1)/(siteArr.x2-siteArr.x1);
47      //如果斜率不为0 则夹角不为0,则不进行切换
48         if(k){
49             return 1;
50         }
51      }else {
52         return 0;
53      }
54 }
55                                                         

 

 判断鼠标停留时长

 当用户在主菜单一个子栏目中停留300ms,我们就认为用户是想进行切换查看其它子菜单。

 所以之前上面?提到的暂不切换的情况:当 最终位置在坐标系1,2区域时,暂不进行切换,但如果鼠标停留时间大于300ms则需要进行切换。

 切换显示子菜单主要代码: 

  在显示切换菜单方法中调用 getSlope 方法 并将当前 主菜单的栏目元素 传给 getSlope(set),其余看备注吧。

 1   var hideTime = 0;  //定时器时间
 2    var flag;    //是否切换标识,0则切换,1不切换
 3    $(".menuContent .item").mouseenter(function(){
 4         var self = $(this);
 5         var obj = [];
 6         var set = {
 7                 left : self.offset().left,
 8                 top : self.offset().top,
 9                 lx : self.offset().left + self.outerWidth(),
10                 ty : self.offset().top + self.outerHeight()
11             }
12        flag = angle.getSlope(set); //调用上面的方法,0则切换,1不切换
13        clearTimeout(hideTime);    //清除定时器
14 
15        //如果flag为0说明需要切换,去除当前选中及显示子菜单样式,切换至新子菜单
16        if(!flag) {
17            clearTimeout(hideTime);
18            $(".menuContent .item").removeClass('js-menu-item-on');
19            self.addClass('js-menu-item-on');
20            $(".submenu").hide();
21            var selector = self.attr('data-id');
22            $('.'+selector).show();
23 
24        }
25     //如果flag为1则不进行切换,但如果用户鼠标停留时长大于300ms则进行切换
26        else {
27            var cur = this;
28            var pre = $(".menuContent").find('.js-menu-item-on')[0];
29            hideTime = setTimeout(function(){
30                if(pre != cur){
31                    $(".menuContent .item").removeClass('js-menu-item-on');
32                    self.addClass('js-menu-item-on');
33                    $(".submenu").hide();
34                    var selector = self.attr('data-id');
35                    $('.'+selector).show();
36                 }
37            },300);
38        }
39   })  

 

虽然只是一个分类菜单显示切换,但好的用户体验也是需要的不是~

嗯,核心是判断鼠标滑动角度 和 鼠标停留时间来进行切换。

jd首页的子菜单就有这种优化,可以试试,就知道我在这瞎白活什么了。?

 

转载于:https://www.cnblogs.com/redjoy/p/7270193.html

相关文章:

  • [NOIP2015] 运输计划
  • 【搜索】POJ-3669 BFS
  • Django model字段类型参考列表
  • 拓扑排序的原理及其实现
  • oracle11g 在azure云中使用rman进行实例迁移
  • Python三种排序算法
  • 最纯粹的直播技术实战02-Camera的处理以及推流
  • 一、MyBatis基本用法——3-Mapper XML映射文件
  • @Autowired和@Resource装配
  • ES6--ArrayBuffer
  • HDU 6078 Wavel Sequence
  • java io
  • 1.spring、mybatis、mysql整合需要的包
  • html行内元素和块级元素及其居中问题
  • 贝叶斯来理解高斯混合模型GMM
  • 【Leetcode】101. 对称二叉树
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 11111111
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Centos6.8 使用rpm安装mysql5.7
  • echarts的各种常用效果展示
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • Facebook AccountKit 接入的坑点
  • IDEA 插件开发入门教程
  • Javascript设计模式学习之Observer(观察者)模式
  • mysql常用命令汇总
  • php的插入排序,通过双层for循环
  • Python连接Oracle
  • 阿里研究院入选中国企业智库系统影响力榜
  • 初识MongoDB分片
  • 从伪并行的 Python 多线程说起
  • 关于使用markdown的方法(引自CSDN教程)
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 深度学习入门:10门免费线上课程推荐
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • 湖北分布式智能数据采集方法有哪些?
  • ​Python 3 新特性:类型注解
  • # Apache SeaTunnel 究竟是什么?
  • #define、const、typedef的差别
  • #pragma pack(1)
  • (4.10~4.16)
  • (C语言)fgets与fputs函数详解
  • (C语言)二分查找 超详细
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (二十四)Flask之flask-session组件
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (十八)三元表达式和列表解析
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .libPaths()设置包加载目录
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET Core Web APi类库如何内嵌运行?