一个端午节,外面人山人海,又那么热,我认为宅在家里看看慕课网,充实自己来的实际...

这是一个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>&gt</i></a>
</dt>
<dd>
<a href="#">曲面电视</a>
<a href="#">超薄电视</a>
<a href="#">HDR电视</a>
<a href="#">DLED电视</a>
</dd>
<dt>
<a href="#">空调<i>&gt</i></a>
</dt>
<dd>
<a href="#">挂壁式空调</a>
<a href="#">柜式空调</a>
<a href="#">中央空调</a>
<a href="#">以旧换新</a>
</dd>
<dt>
<a href="#">洗衣机<i>&gt</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>&gt</i></a>
</dt>
<dd>
<a href="#">手机</a>
<a href="#">对讲机</a>
<a href="#">以旧换新</a>
<a href="#">手机维修</a>
</dd>
<dt>
<a href="#">运营商<i>&gt</i></a>
</dt>
<dd>
<a href="#">合约机</a>
<a href="#">选号机</a>
<a href="#">固定电话</a>
<a href="#">办宽带</a>
</dd>
<dt>
<a href="#">手机配件<i>&gt</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>&gt</i></a>
</dt>
<dd>
<a href="#">笔记本</a>
<a href="#">游戏本</a>
<a href="#">平板电脑</a>
</dd>
<dt>
<a href="#">电脑配件<i>&gt</i></a>
</dt>
<dd>
<a href="#">显示器</a>
<a href="#">CPU</a>
<a href="#">主板</a>
</dd>
<dt>
<a href="#">外设产品<i>&gt</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>&gt</i></a>
</dt>
<dd>
<a href="#">烹饪锅具</a>
<a href="#">刀剪配件</a>
<a href="#">厨房配件</a>
<a href="#">水具酒具</a>
</dd>
<dt>
<a href="#">家纺<i>&gt</i></a>
</dt>
<dd>
<a href="#">床品套件</a>
<a href="#">被子</a>
<a href="#">枕芯</a>
<a href="#">蚊帐</a>
</dd>
<dt>
<a href="#">生活日用<i>&gt</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>&gt</i></a>
</dt>
<dd>
<a href="#">商城同款</a>
<a href="#">当季热卖</a>
<a href="#">2017新品</a>
<a href="#">连衣裙</a>
</dd>
<dt>
<a href="#">男装<i>&gt</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>&gt</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)的更多相关文章

  1. Js实现京东无延迟菜单效果(demo) 慕课网

    先来理清思路:1.开发基本的菜单结构 2.开发普通的二级菜单效果 3.假如延迟解决移动问题 切换子菜单时候,用setTimeout设置延迟 debounce去抖技 在事件被频繁触发是,只执行一次处理 ...

  2. 原生JS通过勾股定理计算苹果菜单效果

    JS原生苹果菜单效果 知识点: 勾股定理 a²+b²=c² Event 是一个事件对象,当一个事件发生后,和当前事件发生相关的详细信息会被临时存储到一个指定的地方,也就是event对象,以方便我们在需 ...

  3. 用js枚举实现简易菜单效果

    用js枚举实现简易菜单效果,左侧显示菜单,右侧显示用户选择的菜单,一图胜千言,还是直接来张效果图吧: 以下是代码: <DOCTYPE html> <html> <head ...

  4. 模仿京东顶部搜索条效果制作的一个小demo

    最近模仿京东顶部搜索条效果制作的一个小demo,特贴到这里,今后如果有用到可以参考一下,代码如下 #define kScreenWidth [UIScreen mainScreen].bounds.s ...

  5. JavaScript js无间断滚动效果 scrollLeft方法 使用模板

    JavaScript js无间断滚动效果 scrollLeft方法 使用模板 <!DOCTYPE HTML><html><head><meta charset ...

  6. 通过JS模拟select表单,达到美化效果[demo][转]

    转自: http://www.cnblogs.com/dreamback/p/SelectorJS.html 通过JS模拟select表单,达到美化效果 Demo ------------------ ...

  7. js下拉框二级关联菜单效果代码具体实现

    这篇文章介绍了js下拉框二级关联菜单效果代码具体实现,有需要的朋友可以参考一下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...

  8. 通过JS模拟select表单,达到美化效果[demo]

    .m-form{background:#fff;padding:50px;font-family:12px/1.5 arial,\5b8b\4f53,sans-serif;} .m-form ul,. ...

  9. js鼠标滚轮滚动图片切换效果

    效果体验网址:http://keleyi.com/keleyi/phtml/image/12.htm HTML文件代码: <!DOCTYPE html PUBLIC "-//W3C// ...

随机推荐

  1. gulp 学习笔记

    以这次学习gulp为契机来同时了解和学习node相关的知识和概念,比如 npm,package.json等,为以后学习node打好基础. 目录   npm     查看模块     安装模块      ...

  2. div模拟输入框input/textarea

    //html<!--填写信息--> <div class="info-wrap"> <form class="formToCheck&quo ...

  3. GPIO的配置过程

    今天看到一篇很好的博文,,看这里:http://www.cnblogs.com/crazyxu/archive/2011/10/14/2212337.html 下面总结一下,加深一下理解. 要使用GP ...

  4. oracle 归档日志满 报错ORA-00257: archiver error. Connect internal only, until freed

    归档日志满导致无法用户无法登陆 具体处理办法 --用户登陆 Microsoft Windows [Version 6.1.7601] Copyright (c) Microsoft Corporati ...

  5. 如何使用HTML5自定义数据属性

    在本文中,我将向你介绍如何使用HTML5自定义数据属性.我还将向你介绍一些开发人员在工作中经常使用的优秀实例. 为什么需要自定义数据属性? 很多时候我们需要存储一些与不同DOM元素相关联的信息.这些信 ...

  6. focus、blur事件的事件委托处理(兼容各个流浏览器)

    今天工作中遇到个问题,问题是这样的,一个form表单中有比较多的input标签,因为form中的input标签中的值都需要前端做客户端校验,由于本人比较懒而且特不喜欢用循环给 每个input元素添加b ...

  7. MySQL安装、输入密码闪退、workbench使用

    1.安装 安装就不细说了,网上一搜一大堆,但是教程推荐这个: wikihow 网站是wikiHOW,很有意思的网站,比百度经验强大很多. 2.输入密码闪退 安装完成后,在开始菜单,打开 开始程序 界面 ...

  8. java并发程序——Excutor

    概述 Excutor这个接口用的不多,但是ThreadPoolExcutor这个就用的比较多了,ThreadPoolExcutor是Excutor的一个实现.Excutor体系难点没有,大部分的关键点 ...

  9. 0基础搭建Hadoop大数据处理-初识

    在互联网的世界中数据都是以TB.PB的数量级来增加的,特别是像BAT光每天的日志文件一个盘都不够,更何况是还要基于这些数据进行分析挖掘,更甚者还要实时进行数据分析,学习,如双十一淘宝的交易量的实时展示 ...

  10. redis 编译安装(生产环境推荐)

    一.安装redis 1.下载redis包 wget http://download.redis.io/releases/redis-3.2.1.tar.gz 2.解压redis包到/opt下 tar ...