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// ...
随机推荐
- onclick = xxx这种赋值写法绑定事件的原理是什么?
本文转自知乎貘吃馍香的回答 提问:刚入门不久,能力有限,这个问题我描述起来有点困难,只有劳烦各位大神细看了 我之前一直以为js底层存在类似下面这样的代码: //给所有dom对象定义好onclick值为 ...
- Robot framework的介绍
Robot framework是基于Python语言编写的功能自动化测试框架.使用简单,不懂编码的测试人员也能像编程一样写测试用例,支持关键字驱动测试并且可以开发系统关键字.还有丰富的第三方库,比如S ...
- 给 endv 取个好名字有赏!
给 endv 取个好名字有赏! 直接回复即可 给 endv 取个好名字,拆分原则 endv = endv endv = end+v endv = en+d+v endv = en+dv endv = ...
- ssh相关命令
ssh命令 ssh命令是openssh套件中的客户端连接工具,可以给予ssh加密协议实现安全的远程登录服务器. 语法ssh(选项)(参数)选项 -1:强制使用ssh协议版本1: -2:强制使用ssh协 ...
- 论.net平台的切身感触(惑)
这篇博客只是作者客观看法,不喜勿喷,条条大路通罗马,路不同风景也不一样,接下来的路该怎么走? 简介:作者.net程序员一枚,工作已有四年,接触过.net平台winform,webform,mvc的开发 ...
- nginx源码编译问题
[root@localhost nginx-1.7.4]# ./configure checking for OS + Linux 2.6.32-431.el6.x86_64 x86_64 check ...
- oh-my-zsh 安装和使用
oh-my-zsh是github用户robbyrussell的一款为简化zsh配置而开发的开源项目. 其github地址:https://github.com/robbyrussell/oh-my-z ...
- Objective-C 实用关键字详解1「面试、工作」看我就 🐒 了 ^_^.
在写项目 或 阅读别人的代码(一些优秀的源码)中,总能发现一些常见的关键字,随着编程经验的积累大部分还是知道是什么意思 的. 相信很多开发者跟我当初一样,只是基本的常用关键字定义属性会使用,但在关键字 ...
- zabbix主动上报的python脚本
本代码linux.window平台通用. 不过我遇到一个Windows2008缺少运行库的提示,可能这个是Python3.6开发的.需要安装vc2015运行库吧.我没调试成功. linux平台还可以监 ...
- 【原创】bootstrap框架的学习 第六课[bootstrap代码]
Bootstrap 允许您以两种方式显示代码: 第一种是 <code> 标签.如果您想要内联显示代码,那么您应该使用 <code> 标签. 第二种是 <pre> 标 ...