이 글의 예시는 참고용으로 Baidu 뉴스 탐색 메뉴 슬라이딩 애니메이션을 구현하기 위해 jquery를 공유하는 것입니다.
아이디어와 단계
1. UL을 사용하여 간단한 수평 탐색을 만듭니다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>仿百度新闻菜单滑动动画</title> <style type="text/css"> body, div, ul, li, a { margin: 0px; padding: 0px; font-size: 20px; color: #FFF; border: 0; } .div-nav-container { margin-top: 50px; width: 100%; background-color: #01204F; } .div-nav { width: 870px; margin: 0px auto; } ul { list-style: outside none none; width: 100%; height: 50px; } ul li { float: left; } ul li a { line-height: 50px; display: block; padding: 0px 15px; text-align: center; text-decoration: none; } </style> </head> <body> <div class="div-nav-container"> <div class="div-nav"> <ul> <li><a href="javascript:void(0)">网站首页</a></li> <li><a href="javascript:void(0)">热点</a> </li> <li><a href="javascript:void(0)">国际新闻</a> </li> <li><a href="javascript:void(0)">国内新闻</a> </li> <li><a href="javascript:void(0)">国家政策</a> </li> <li><a href="javascript:void(0)">体育新闻</a> </li> <li><a href="javascript:void(0)">娱乐新闻</a> </li> <li><a href="javascript:void(0)">名人</a> </li> <li><a href="javascript:void(0)">古迹</a> </li> </ul> </div> </div> </body> </html>
2. 메뉴 슬라이딩 애니메이션을 위해 div-hover라는 이름의 div를 추가하고 CSS 스타일을 설정합니다.
<style type="text/css"> .div-hover { background-color: Red;height: 50px; left: 0px; top: 0px; width: 0px; } </style> <div class="div-nav"> <!--添加滑动背景--> <div class="div-hover"> </div> <ul> ... </ul> </div>
<script type="text/javascript"> var divHoverLeft = 0; var aWidth = 0; $(document).ready(function () { $("a").on({ 'mouseover': function () { SetDivHoverWidthAndLeft(this); //设置滑动动画 $(".div-hover").stop().animate({ width: aWidth, left: divHoverLeft }, 150); } }); }); function SetDivHoverWidthAndLeft(element) { divHoverLeft = GetLeft(element); aWidth = GetWidth(element); } //获得Li宽度 function GetWidth(ele) { return $(ele).parent().width(); } //获得div-hover左边距 function GetLeft(element) { //获得li之前的同级li元素 var menuList = $(element).parent().prevAll(); var left = 0; //计算背景遮罩左边距 $.each(menuList, function (index, ele) { left += $(ele).width(); }); return left; } </script>
미리보기 효과에서 알 수 있듯이 div-hover 위치에 문제가 있습니다. div-hover는 상위 요소와 절대 위치해야 하므로 수정된 코드(주석 부분이 수정 지점입니다) 다음과 같습니다:
<style type="text/css"> .div-nav { width: 870px; margin: 0px auto; /*作为div-hover的父元素定位参照*/ position: relative; } .div-hover { background-color: Red; height: 50px; left: 0px; top: 0px; width: 0px; /*以父元素绝对定位*/ position: absolute; } </style>
위치 문제가 해결되었음에도 불구하고 배경 이미지는 여전히 텍스트 위에 떠 있으므로 빨간색 div 위에 텍스트가 뜨도록 코드가 조정됩니다.
<style type="text/css"> ul li { float: left; /*****Start(作用:导航文字浮于div-hover红色之上)*******/ position: relative; z-index: 4; /*********************End*************************/ } </style>
4. 로딩 페이지에 메뉴 클릭 및 기본 메뉴 선택 추가
<style type="text/css"> /**设置菜单激活***/ .active { background-color: Red; } </style> <script type="text/javascript"> var divHoverLeft = 0; var aWidth = 0; $(document).ready(function () { $("a").on({ 'mouseover': function () { SetDivHoverWidthAndLeft(this); //设置滑动动画 $(".div-hover").stop().animate({ width: aWidth, left: divHoverLeft }, 150); }, /*添加点击事件*/ 'click': function () { SetDivHoverWidthAndLeft(this); //清除所有a标签class $('a').removeClass(); //设置当前点击菜单为激活状态 $(this).addClass('active'); } }); }); </script> </head> <body> <div class="div-nav-container"> <div class="div-nav"> <!--添加滑动背景--> <div class="div-hover"> </div> <ul> <--默认菜单激活--> <li><a class="active" href="javascript:void(0)">网站首页</a></li> ………… </ul> </div> </div> </body> </html>
5. 마우스를 범위 밖으로 이동하여 현재 활성화된 요소를 자동으로 찾는 기능을 추가합니다.
이 기능을 수행하기 전에 먼저 생각해 보겠습니다. 마우스 아웃 작업의 경우 mouseout 및 mouseleave 이벤트를 생각할 수 있으며 다음과 같은 질문이 있습니다.①이 조건을 충족하려면 이곳에서 어떤 이벤트를 선택해야 합니까?
②선택한 이벤트는 어떤 요소에 위치하나요?
③마우스를 밖으로 옮긴 후 현재 어떤 요소가 활성화되어 있는지 어떻게 알 수 있나요?
④div-hover의 왼쪽 여백과 너비에 해당하는 값을 어떻게 알 수 있나요?
연습을 통해 진정한 지식을 얻고, 연습해 보세요.
우선 마우스아웃을 예로 들면, 첫 번째 문제는 자연스럽게 해결됩니다.
둘째, 이벤트가 위치한 요소는 무엇입니까? 위의 GIF 다이어그램 분석을 통해 위치 지정이 A 태그 또는 Li 태그에 있는 경우 A 태그 또는 Li 태그 사이를 전환하는 마우스 이동 작업도 활성 요소에 대한 자동 위치 지정을 트리거합니다(자동이라고 가정). 위치 지정이 완료됨) 다음 그림이 표시됩니다.
따라서 A나 Li 태그에 위치할 수 없습니다. 다시 생각해 보면 마우스를 전체 탐색 범위 밖으로 이동해야 합니다. 그러면 어떤 요소를 위치시켜야 하는지 쉽게 알 수 있습니다. UL 또는 UL의 상위 요소의 크기 범위는 동일하므로 두 요소 모두 괜찮습니다. 두 요소의 크기가 일치하지 않으면 UL에 배치해야 합니다. 그래서 다음과 비슷한 코드가 있습니다.
그러면 현재 활성화된 요소를 어떻게 알 수 있나요? 숨겨진 필드나 다른 표시 방법을 사용하여 이벤트를 클릭했을 때 현재 클릭한 요소의 너비와 왼쪽 여백을 저장할 수 있습니다. 데이터를 다시 읽은 후 애니메이션 위치 지정을 진행하면 위의 ③ ④ 코드 부분이 해결됩니다.
$("ul").on({ 'mouseout': function (event) { /*动画定位div-hover位置到激活元素*/ } });
效果展示:
看图发现依旧出现之前类似定位在A或Li的问题,出现这种情况的原因:
jquery中mouseout如果定位在一个元素上,例如div,那么此div之下的元素都会具有mouseout事件,也就是常说的,事件冒泡机制;与此类似的事件如mousedown,mouseover等,那么是不是阻止事件冒泡就行了呢? 理论上是这样的。通常阻止冒泡有两种方式: event.stopPropagation();和return false;当然他们之间也是有区别的。
相关代码修改如下:
<script type="text/javascript"> .......... $(document).ready(function () { /*鼠标滑出UL或者div-nav背景div-hover自动定位到激活菜单处*/ $("ul").on({ 'mouseout': function (event) { $(".div-hover").stop().animate({ width: $(".h-width").val(), left: $(".h-left").val() }, 150); /**阻止冒泡**/ event.stopPropagation(); //return false; } }); }); ....... </script>
无论何种阻止方式,都没有卵用,依旧阻止不了冒泡,效果可想而知,与上面Gif图所示无异;
由此证明,mouseover在实现此功能方面是有问题的;
那换mouseleave呢,除了将mouseover修改为mouseleave和去除冒泡代码外,其他代码不做改动,实验效果如下:
从上图可以看出,效果与百度新闻导航滑动基本无异,至此大功告成;
完整代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>仿百度新闻菜单滑动动画</title> <style type="text/css"> body, div, ul, li, a { margin: 0px; padding: 0px; font-size: 20px; color: #FFF; border: 0; } .div-nav-container { margin-top: 50px; width: 100%; background-color: #01204F; } .div-nav { /*作为div-hover的父元素定位参照*/ position: relative; width: 870px; margin: 0px auto; } .div-hover { background-color: Red; /*以父元素绝对定位*/ position: absolute; height: 50px; left: 0px; top: 0px; width: 0px; } ul { list-style: outside none none; width: 100%; height: 50px; } ul li { float: left; /*****Start(作用:导航文字浮于div-hover红色之上)*******/ position: relative; z-index: 4; /*********************End*************************/ } ul li a { line-height: 50px; display: block; padding: 0px 15px; text-align: center; text-decoration: none; } /**设置菜单激活***/ .active { background-color: Red; } </style> <script src="../js/jquery-1.11.3.min.js" type="text/javascript"></script> <script type="text/javascript"> var divHoverLeft = 0; var aWidth = 0; $(document).ready(function () { //菜单滑动动画 $("a").on({ /*此处用mouseover或者mouseenter均可,如果以后要为X标签同时添加悬停和移出事件,建议用enter和leave也就是传说中的hover事件,因为里面事件冒泡已经处理过,就不会出现类似over和out之类的情况了*/ 'mouseenter': function () { SetDivHoverWidthAndLeft(this); //设置滑动动画 $(".div-hover").stop().animate({ width: aWidth, left: divHoverLeft }, 150); }, 'click': function () { SetDivHoverWidthAndLeft(this); //清除所有a标签class $('a').removeClass(); //设置当前点击菜单为激活状态 $(this).addClass('active'); $(".h-width").val(aWidth); $(".h-left").val(divHoverLeft); } }); /*鼠标滑出UL或者div-nav背景div-hover自动定位到激活菜单处*/ //mouseleave事件定位到ul或者div-nav均可 $("ul").on({ 'mouseleave': function (event) { $(".div-hover").stop().animate({ width: $(".h-width").val(), left: $(".h-left").val() }, 150); } }); }); function SetDivHoverWidthAndLeft(element) { divHoverLeft = GetLeft(element); aWidth = GetWidth(element); } //获得Li宽度 function GetWidth(ele) { return $(ele).parent().width(); } //获得div-hover左边距 function GetLeft(element) { //获得li之前的同级li元素 var menuList = $(element).parent().prevAll(); var left = 0; //计算背景遮罩左边距 $.each(menuList, function (index, ele) { left += $(ele).width(); }); return left; } </script> </head> <body> <div class="div-nav-container"> <div class="div-nav"> <!--添加滑动背景--> <div class="div-hover"> </div> <ul> <li><a class="active" href="javascript:void(0)">网站首页</a></li> <li><a href="javascript:void(0)">热点</a> </li> <li><a href="javascript:void(0)">国际新闻</a> </li> <li><a href="javascript:void(0)">国内新闻</a> </li> <li><a href="javascript:void(0)">国家政策</a> </li> <li><a href="javascript:void(0)">体育新闻</a> </li> <li><a href="javascript:void(0)">娱乐新闻</a> </li> <li><a href="javascript:void(0)">名人</a> </li> <li><a href="javascript:void(0)">古迹</a> </li> </ul> </div> </div> <input type="hidden" class="h-width" value="110" /> <input type="hidden" class="h-left" value="0" /> </body> </html>
总结和关键点
1.背景滑动由某个块状元素(此处用的div)来实现,而非本元素的hover改变背景颜色;
2.注意元素定位(滑动块状元素以谁来绝对定位或者相对定位,左边距的计算和自身宽度的计算;滑动块状元素div-hover和li之间的相对定位,以及层级大小);
3.滑动动画事件animate和记录激活菜单,鼠标移出区域自定定位到激活菜单;
4.jquery中mouseover,mouseout以及mouseenter,mouseleave关于冒泡机制的区别;(前两个未做冒泡机制的限制,后两个冒泡已经经过处理,事件只针对注册元素本身,而不会对子元素起作用,mouseenter和mouseleave用在一个元素标签上可以用hover事件代替,本身hover就是这两者的封装,如果事件在不同元素标签上,最好分开调用mouseenter和mouseleave事件)
5.所有关键点以及作用都已经在代码各处加上注释,各位可以看看。
希望本文对大家学习jquery程序设计有所帮助。