Js实现京东无延迟菜单效果(demo)
一个端午节,外面人山人海,又那么热,我认为宅在家里看看慕课网,充实自己来的实际...
这是一个js实现京东无延迟菜单效果,感觉很好,分享给大家...
先来理清思路:
1.开发基本的菜单结构 2.开发普通的二级菜单效果 3.假如延迟解决移动问题
切换子菜单时候,用setTimeout设置延迟 debounce去抖技
在事件被频繁触发是,只执行一次处理 4.解决延迟引入的新问题
跟踪鼠标的移动
用鼠标当前位置,和鼠标上一次位置与子菜单上下边缘的三角形区域进行比较 运用到向量
二位向量叉乘公式
用叉乘法判断点在三角形内
最终效果:鼠标自然的移动和点击到子菜单
切换时无延迟
下面开始代码:
开发基本的菜单结构
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>京东菜单无刷新</title>
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/mche.js"></script>
<script src="js/function.js"></script> <style>
.wrap{
position:relative;
width:200px;
left:50px;
top:50px;
} ul{
padding:15px;
margin:9;
list-style:none;
background:#6c6669;
color:#ffffff;
border-right-width:0;
} /*水平居中*/
li{
display:block;
height:30px;
line-height: 30px;
padding-left:12px;
cursor:pointer;
font-size: 14px;
position:relative;
} /*鼠标移动上去的背景色*/
li.active{
background:#999395;
} /*js可以很好地调用类,一般效果css实现就好*/
li span:hover{
color:#c81623;
} /*隐藏的类*/
.none{
display: none;
} /*二级菜单*/
#sub{
width:600px;
position: absolute;
border:1px solid #f7f7f7;
background:#f7f7f7;
box-shadow:2px 0 rgba(0,0,0,.3);
left: 200px;
top:0;
box-sizing:border-box;
margin: 0px;
padding:10px;
} .sub-content a{
font-style:12px;
color:#666;
text-decoration:none;
} .sub-content dd a{
border-left:1px solid #e0e0e0;
padding:0 1px;
margin:4px 0;
} .sub-content dl {
overflow:hidden;
} .sub-content dt{
float: left;
width:70px;
font-weight: bold;
clear:left;
position:relative;
} .sub-content dd {
float: left;
margin-left: 5px;
border-top:1px solid #eee;
margin-bottom: 5px;
} .sub-content dt i{
width:4px;
height: 14px;
font:400 9px/14px consolas;
position: absolute;
right:5px;
top:5px;
}
</style>
</head>
<body>
<div class="wrap" id="test">
<ul>
<li data-id="a">
<span>家用电器</span>
</li>
<li data-id="b">
<span>手机 / 运营商 / 数码</span>
</li>
<li data-id="c">
<span>电脑办公 / 办公</span>
</li>
<li data-id="d">
<span>家居 / 家具 / 家装 / 厨具</span>
</li>
<li data-id="e">
<span>男装 / 女装 / 童装 / 内衣 </span>
</li>
<li data-id="f">
<span>美妆个护 / 宠物 </span>
</li>
<li data-id="g">
<span>女鞋 / 箱包 / 钟表 / 珠宝 </span>
</li>
<li data-id="h">
<span>男鞋 / 运动 / 户外</span>
</li>
<li data-id="i">
<span>汽车 / 汽车用品 </span>
</li>
</ul>
<div id="sub" class="none">
<div id="a" class="sub-content none">
<dl>
<dt>
<a href="#">电视<i>></i></a>
</dt>
<dd>
<a href="#">曲面电视</a>
<a href="#">超薄电视</a>
<a href="#">HDR电视</a>
<a href="#">DLED电视</a>
</dd>
<dt>
<a href="#">空调<i>></i></a>
</dt>
<dd>
<a href="#">挂壁式空调</a>
<a href="#">柜式空调</a>
<a href="#">中央空调</a>
<a href="#">以旧换新</a>
</dd>
<dt>
<a href="#">洗衣机<i>></i></a>
</dt>
<dd>
<a href="#">滚筒式洗衣机</a>
<a href="#">洗烘一体机</a>
<a href="#">波轮洗衣机</a>
<a href="#">迷你洗衣机</a>
</dd>
</dl>
</div>
<div id="b" class="sub-content none"> <dl>
<dt>
<a href="#">手机通讯<i>></i></a>
</dt>
<dd>
<a href="#">手机</a>
<a href="#">对讲机</a>
<a href="#">以旧换新</a>
<a href="#">手机维修</a>
</dd>
<dt>
<a href="#">运营商<i>></i></a>
</dt>
<dd>
<a href="#">合约机</a>
<a href="#">选号机</a>
<a href="#">固定电话</a>
<a href="#">办宽带</a>
</dd>
<dt>
<a href="#">手机配件<i>></i></a>
</dt>
<dd>
<a href="#">手机壳</a>
<a href="#">贴膜</a>
<a href="#">手机存储卡</a>
<a href="#">数据线</a>
</dd>
</dl>
</div>
<div id="c" class="sub-content none">
<dl>
<dt>
<a href="#">电脑整机<i>></i></a>
</dt>
<dd>
<a href="#">笔记本</a>
<a href="#">游戏本</a>
<a href="#">平板电脑</a>
</dd>
<dt>
<a href="#">电脑配件<i>></i></a>
</dt>
<dd>
<a href="#">显示器</a>
<a href="#">CPU</a>
<a href="#">主板</a>
</dd>
<dt>
<a href="#">外设产品<i>></i></a>
</dt>
<dd>
<a href="#">鼠标</a>
<a href="#">键盘</a>
<a href="#">键盘套餐</a>
</dd>
</dl>
</div>
<div id="d" class="sub-content none">
<dl>
<dt>
<a href="#">厨具<i>></i></a>
</dt>
<dd>
<a href="#">烹饪锅具</a>
<a href="#">刀剪配件</a>
<a href="#">厨房配件</a>
<a href="#">水具酒具</a>
</dd>
<dt>
<a href="#">家纺<i>></i></a>
</dt>
<dd>
<a href="#">床品套件</a>
<a href="#">被子</a>
<a href="#">枕芯</a>
<a href="#">蚊帐</a>
</dd>
<dt>
<a href="#">生活日用<i>></i></a>
</dt>
<dd>
<a href="#">收纳用品</a>
<a href="#">雨伞雨具</a>
<a href="#">净化除味</a>
<a href="#">浴室用品</a>
</dd>
</dl>
</div>
<div id="e" class="sub-content none">
<dl>
<dt>
<a href="#">女装<i>></i></a>
</dt>
<dd>
<a href="#">商城同款</a>
<a href="#">当季热卖</a>
<a href="#">2017新品</a>
<a href="#">连衣裙</a>
</dd>
<dt>
<a href="#">男装<i>></i></a>
</dt>
<dd>
<a href="#">商城同款</a>
<a href="#">当季热卖</a>
<a href="#">2017新品</a>
<a href="#">牛仔裤</a>
</dd>
</dl>
</div>
<div id="f" class="sub-content none">
<dl>
<dt>
<a href="#">面部护肤<i>></i></a>
</dt>
<dd>
<a href="#">补水保湿</a>
<a href="#">卸妆</a>
<a href="#">洁面</a>
</dd>
</dl>
</div>
</div>
</ul>
</body>
</html>
解决第2、3个问题
$(document).ready(function(){
var sub = $('#sub')
var activeRow
var activeMenu
var timer
var mouseInSub = false
sub.on('mouseenter',function(e){
mouseInSub = true
}).on('mouseleave',function(e){
mouseInSub = false
})
var mouseTrack = []
var moveHandler = function(e){
mouseTrack.push({
x:e.pageX,
y:e.pageY
})
if(mouseTrack.length > 3){
mouseTrack.shift()
}
}
$('#test')
.on('mouseenter',function(e){
sub.removeClass('none')
$(document).bind('mousemove',moveHandler)
})
.on('mouseleave',function(e){
sub.addClass('none')
if(activeRow){
activeRow.removeClass('active')
activeRow = null;
}
if(activeMenu){
activeMenu.addClass('none')
activeMenu = null;
}
//解绑
$(document).unbind('mousemove',moveHandler)
})
.on('mouseenter','li',function(e){
if(!activeRow){
activeRow = $(e.target).addClass('acrive')
activeMenu = $('#'+activeRow.data('id'))
activeMenu.removeClass('none')
return
}
//清除
if(timer){
clearTimeout(timer)
}
//鼠标当前坐标
var currMousePos = mouseTrack[mouseTrack.length - 1]
//上次的坐标
var leftCorner = mouseTrack[mouseTrack.length-2]
var delay = needDelay(sub,leftCorner,currMousePos)
if(delay){
// 时间触发,设置一个缓冲期
timer = setTimeout(function(){
//判断
if(mouseInSub){
return
}
activeRow.removeClass('active')
activeMenu.addClass('none')
activeRow = $(e.target)
activeRow.addClass('active')
activeMenu = $('#'+ activeRow.data('id'))
activeMenu.removeClass('none')
timer = null
}, 300)
}else{
var prevActiveRow = activeRow
var prevActiveMenu = activeMenu
activeRow = $(e.target)
activeMenu = $('#' + activeRow.data('id'))
prevActiveRow.removeClass('active')
prevActiveMenu.addClass('none')
activeRow.addClass('active')
activeMenu.removeClass('none')
}
})
})
解决延迟引入的新问题
function sameSign(a,b){
return (a ^ b) >= 0
}
function vector(a,b){
return{
x:b.x - a.x,
y:b.y - a.y
}
}
function vectorProduct(v1,v2){
return v1.x * v2.y - v2.x * v1.y
}
function isPointInTrangle(p,a,b,c){
var pa = vector(p,a)
var pb = vector(p,b)
var pc = vector(p,c)
var t1 = vectorProduct(pa,pb)
var t2 = vectorProduct(pb,pc)
var t3 = vectorProduct(pc,pa)
return sameSign(t1,t2) && sameSign(t2,t3)
}
function needDelay(elem,leftCorner,currMousePos){
var offset = elem.offset()
var topLeft = {
x:offset.left,
y:offset.top
}
var bottomLeft = {
x:offset.left,
y:offset.top + elem.height()
}
return isPointInTrangle(currMousePos,leftCorner,topLeft,bottomLeft)
}
当你看到这,也就实现了京东的无延迟菜单效果,同时也为你点赞,能看到这儿。

一入IT行业深似海,给我的感觉,,保持一个积极学习的心态是必须的,用博客记录我前进的脚步。
有什么问题,可以留言,大家一起讨论,一起进步。
欢迎大家关注我的 订阅号:博客乐园

Js实现京东无延迟菜单效果(demo)的更多相关文章
- Js实现京东无延迟菜单效果(demo) 慕课网
先来理清思路:1.开发基本的菜单结构 2.开发普通的二级菜单效果 3.假如延迟解决移动问题 切换子菜单时候,用setTimeout设置延迟 debounce去抖技 在事件被频繁触发是,只执行一次处理 ...
- 原生JS通过勾股定理计算苹果菜单效果
JS原生苹果菜单效果 知识点: 勾股定理 a²+b²=c² Event 是一个事件对象,当一个事件发生后,和当前事件发生相关的详细信息会被临时存储到一个指定的地方,也就是event对象,以方便我们在需 ...
- 用js枚举实现简易菜单效果
用js枚举实现简易菜单效果,左侧显示菜单,右侧显示用户选择的菜单,一图胜千言,还是直接来张效果图吧: 以下是代码: <DOCTYPE html> <html> <head ...
- 模仿京东顶部搜索条效果制作的一个小demo
最近模仿京东顶部搜索条效果制作的一个小demo,特贴到这里,今后如果有用到可以参考一下,代码如下 #define kScreenWidth [UIScreen mainScreen].bounds.s ...
- JavaScript js无间断滚动效果 scrollLeft方法 使用模板
JavaScript js无间断滚动效果 scrollLeft方法 使用模板 <!DOCTYPE HTML><html><head><meta charset ...
- 通过JS模拟select表单,达到美化效果[demo][转]
转自: http://www.cnblogs.com/dreamback/p/SelectorJS.html 通过JS模拟select表单,达到美化效果 Demo ------------------ ...
- js下拉框二级关联菜单效果代码具体实现
这篇文章介绍了js下拉框二级关联菜单效果代码具体实现,有需要的朋友可以参考一下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...
- 通过JS模拟select表单,达到美化效果[demo]
.m-form{background:#fff;padding:50px;font-family:12px/1.5 arial,\5b8b\4f53,sans-serif;} .m-form ul,. ...
- js鼠标滚轮滚动图片切换效果
效果体验网址:http://keleyi.com/keleyi/phtml/image/12.htm HTML文件代码: <!DOCTYPE html PUBLIC "-//W3C// ...
随机推荐
- Web worker 与JS中异步编程的对比
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...
- jsel、tl是什么
el 表达式是什么? * sun 制订的一种用于计算的一种规则,可以给元素赋值,也可以直接输出 el表达式:${el表达式}实验1:简单的使用el表达式获取值<%request.setAttri ...
- css系列:input的placeholder在safari下设置行高失效
在项目中遇到input的placeholder在safari下设置行高失效的问题,问度娘后未得治原因,倒是有解决办法: 方法一:使用padding使提示文字居中,如果font-size:14px,UI ...
- lua 字符串
lua 字符串 语法 单引号 双引号 "[[字符串]]" 示例程序 local name1 = 'liao1' local name2 = "liao2" lo ...
- Hibernate启动非常慢问题分析
项目中使用hibernate3,在启动项目过程中,发现加载显示数据很慢,要多几分钟才显示出数据,没有报其他异常.今天特别慢,过了好久都不加载显示数据. 排查思路有以下几个方面: 1.数据库是否开启.检 ...
- Docker for Mac与IntelliJ Docker Integration插件的兼容性问题
笔者在自己的Mac上安装的是Docker for Mac,而不是Docker Toolbox. 这两者最主要的区别在于Docker for Mac用HyperKit作为虚拟化解决方案而不是Virtua ...
- Android之AIDL知识总结
1.AIDL介绍 AIDL是一个缩写,全称是Android Interface Definition Language,翻译为Android接口定义语言.主要用于线程之间的通信,本文主要以不同应用之间 ...
- ASP.NET Cookie和Session
Cookie和Session C#在服务器,JS在客户端 客户端验证不能代替服务端验证 Http HTTP属于应用层,HTTP 协议一共有五大特点:1.支持客户/服务器模式;2.简单快速;3.灵活;4 ...
- 【山东省选2008】郁闷的小J 平衡树Treap
小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危险,这也正是他所郁闷的.具体说来,书架由N ...
- codeforces 803B Distances to Zero
Distances to Zero 题目链接:http://codeforces.com/problemset/problem/803/B 题目大意: 给一串数字,求每个数字到离他最近数字0的距离.. ...