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

这是一个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. 用 parseInt()解决的 小 bug

    在做轮播模块的时候遇到问题是:你在 连续指示小按钮 时候再去 只有 点击 下一张按钮,出现bug: 指示小按钮的 className 当前显示的 calssName 为 undefined ! // ...

  2. 分布式锁与实现(一)——基于Redis实现

    概述 目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们"任何一个分布式系统都无法同时满足一致性(Consisten ...

  3. Java 工具类—日期获得,随机数,系统命令,数据类型转换

    package tems; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; ...

  4. OnsenUI 前端框架(三)

    上一章咱们学习了OnsenUI的工具栏.侧边栏和标签栏.通过对页面上这三部分的学习,咱们对混合应用的一个页面有了大体上的认识.从这一章开始,咱们学习OnsenUI混合项目开发过程中会用到的各种各样的组 ...

  5. fuse on TDH4.8

    一.安装依赖包 yum install autoconf.noarch yum install automake yum install libtool* yum install m4 yum ins ...

  6. 苹果笔记本只能上QQ,微信,任何浏览器不能打开网页的问题。

    我的笔记本一共遇到过两次这种情况.第一次是浏览器输入域名打不开网页,而输入ip地址可以打开.这就是DNS服务器的问题,解决方法很简单.在系统偏好设置里面找到网络,然后,点击正在连接的网络的高级选项,选 ...

  7. [ext4]05 磁盘布局 - 延迟块组初始化

    延迟块组初始化,Ext4的新特性.如果对应的特性标识uninit_bg置位,那么inode bitmap和inode tables就不会初始化. 延迟块组初始化特性特性可以减少格式化耗时. 延迟块组初 ...

  8. 学好php可以做的事情真多!

    学好php能做什么?其实学好php能做的事情很多! 一. 学好php可以就业 1:大中小公司通吃. 现在几乎所有有前途的公司都会在互联网上安家.只要在网上安家,就需要找这些方面的技术人员,而且很多公司 ...

  9. 解决oracle用户锁定

        故障现象: SQL> connect scott/scottERROR:ORA-01017: invalid username/password; logon deniedSQL> ...

  10. VopSdk一个高逼格微信公众号开发SDK(源码下载)

    看之前回复很多说明大家很有热情&文章被误删掉了,不想让有的朋友错失这个高逼格的东西,现在重新发布,这次就直接放出源码,文章最末下载地址. 看之前回复很多说明大家很有热情&文章被误删掉了 ...