基于jquery实现百度新闻导航菜单滑动动画


Posted in Javascript onMarch 15, 2016

本文实例为大家分享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,命名div-hover,用于菜单滑动动画,设置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>

3.添加菜单项的滑动事件,计算div-hover的滑动要素,左,上边距以及宽度;

<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>

效果预览

基于jquery实现百度新闻导航菜单滑动动画

从预览效果可以看出,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>

基于jquery实现百度新闻导航菜单滑动动画

虽然解决了定位问题,但是背景图片还是浮于文字上方,所以调整代码,将文字浮动于红色div之上:

<style type="text/css">
  ul li
  {
    float: left; 
    /*****Start(作用:导航文字浮于div-hover红色之上)*******/
    position: relative;
    z-index: 4; 
    /*********************End*************************/
  }
</style>

效果预览

基于jquery实现百度新闻导航菜单滑动动画

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>

效果预览

基于jquery实现百度新闻导航菜单滑动动画

5.添加鼠标移出范围,自动定位当前激活元素功能;

      在做此功能之前,先理下思路,鼠标移出操作,我们可以想到mouseout,mouseleave事件,那么随之就会有以下几个疑问:

       ①这地方选用哪个事件可以满足这个条件呢?

       ②那选择的事件又定位在哪个元素呢?

       ③移出鼠标之后又如何知道当前激活的是哪个元素呢?

       ④如何知道div-hover的左边距和width等值呢?

      实践出真知,那就实践一下:

       首先,以mouseout为例,第一个问题自然就解决了;

       其次,事件定位在哪个元素?通过上面GIF图,分析,如果定位在A标签或Li标签,那么鼠标移出操作在A标签或Li标签之间切换也会触发自动定位到激活元素(假设自动定位已做),就会出现如下图所示情况:

基于jquery实现百度新闻导航菜单滑动动画

所以不能定位在A或Li标签上,再想一下,鼠标应该是移出整个导航的范围才可以,那么定位在哪个元素就很容易出来了,应该定位在UL或者UL的父级元素,他们两个的大小范围均是一致的,所以两个元素均可以,若两个元素大小不一致,就应该定位在UL上面了。于是就有了类似如下代码:

$("ul").on({
   'mouseout': function (event) {
      /*动画定位div-hover位置到激活元素*/
    }
});

      然后,如何知道当前激活为何元素呢,可以在点击事件时,用隐藏域或者其他display方式存储当前点击的元素宽度和左边距,待鼠标移出操作,重新读取存储的数据,进而进行animate定位;从而解决以上③④问题;部分代码如下:

(当然,想知道菜单激活元素,也可以用class为active的方式来查找,不过这种方式,相对来说麻烦一些,首先获得active的元素,然后通过遍历li,重新计算一遍宽度和左边距,最后进行赋值和添加滑动定位;此处暂用隐藏域方式处理,原因是方便简单,群友如有兴趣可以用active方式试验)

<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');
         $(".h-width").val(aWidth);
         $(".h-left").val(divHoverLeft);
       }
     });

     /*鼠标滑出UL或者div-nav背景div-hover自动定位到激活菜单处*/
     $("ul").on({
       'mouseout': function (event) {
         $(".div-hover").stop().animate({ width: $(".h-width").val(), left: $(".h-left").val() }, 150);
       }
     });
  });

  function SetDivHoverWidthAndLeft(element) {
    divHoverLeft = GetLeft(element);
    aWidth = GetWidth(element);
  }
  ............
  </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>
  <input type="hidden" class="h-width" value="110" />
  <input type="hidden" class="h-left" value="0" />
</body>
</html>

效果展示:

基于jquery实现百度新闻导航菜单滑动动画

看图发现依旧出现之前类似定位在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和去除冒泡代码外,其他代码不做改动,实验效果如下:

基于jquery实现百度新闻导航菜单滑动动画

从上图可以看出,效果与百度新闻导航滑动基本无异,至此大功告成;

完整代码

<!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程序设计有所帮助。

Javascript 相关文章推荐
javascript delete 使用示例代码
Mar 29 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
May 12 Javascript
jquery获取tagName再进行判断
May 29 Javascript
解决jquery版本冲突的有效方法
Sep 02 Javascript
Javascript 赋值机制详解
Nov 23 Javascript
javascript实现日期按月份加减
May 15 Javascript
js全选按钮的实现方法
Nov 17 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
Jul 30 Javascript
微信小程序返回多级页面的实现方法
Oct 27 Javascript
解决vue中对象属性改变视图不更新的问题
Feb 23 Javascript
12个提高JavaScript技能的概念(小结)
May 09 Javascript
js在HTML的三种引用方式详解
Aug 29 Javascript
dedecms页面如何获取会员状态的实例代码
Mar 15 #Javascript
JavaScript隐式类型转换
Mar 15 #Javascript
JavaScript正则表达式匹配 div  style标签
Mar 15 #Javascript
Angularjs整合微信UI(weui)
Mar 15 #Javascript
一步步教大家编写酷炫的导航栏js+css实现
Mar 14 #Javascript
原生javascript+css3编写的3D魔方动画旋扭特效
Mar 14 #Javascript
基于javascript html5实现3D翻书特效
Mar 14 #Javascript
You might like
解析如何通过PHP函数获取当前运行的环境 来进行判断执行逻辑(小技巧)
2013/06/25 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
php实现通用的从数据库表读取数据到数组的函数实例
2015/03/21 PHP
php实现RSA加密类实例
2015/03/26 PHP
PHP实现的最大正向匹配算法示例
2017/12/19 PHP
用ADODB.Stream转换
2007/01/22 Javascript
javascript文件中引用依赖的js文件的方法
2014/03/17 Javascript
KnockoutJS 3.X API 第四章之click绑定
2016/10/10 Javascript
boostrapTable的refresh和refreshOptions区别浅析
2017/01/22 Javascript
javascript input输入框模糊提示功能的实现
2017/09/25 Javascript
Vue cli 引入第三方JS和CSS的常用方法分享
2018/01/20 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
2018/01/22 Javascript
JavaScript设计模式之构造函数模式实例教程
2018/07/02 Javascript
ios设备中angularjs无法改变页面title的解决方法
2018/09/13 Javascript
微信小程序开发实现的选项卡(窗口顶部/底部TabBar)页面切换功能图文详解
2019/05/14 Javascript
layui 数据表格复选框实现单选功能的例子
2019/09/19 Javascript
js实现左右轮播图
2020/01/09 Javascript
TypeScript的安装、使用、自动编译的实现
2020/04/10 Javascript
解决Vue 给mapState中定义的属性赋值报错的问题
2020/06/22 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
[03:02]2014DOTA2西雅图邀请赛 让队员自己告诉你DK NAVI备战情况
2014/07/08 DOTA
[51:15]完美世界DOTA2联赛PWL S2 PXG vs Magma 第一场 11.21
2020/11/24 DOTA
python实现在IDLE中输入多行的方法
2018/04/19 Python
Python3使用PySynth制作音乐的方法
2019/09/09 Python
Python-numpy实现灰度图像的分块和合并方式
2020/01/09 Python
python 如何快速复制序列
2020/09/07 Python
python基于socket模拟实现ssh远程执行命令
2020/12/05 Python
世界首屈一指的钓鱼用品商店:TackleDirect
2016/07/26 全球购物
印度尼西亚最完整和最大的在线药房网站:Farmaku.com
2019/11/23 全球购物
初中毕业生的自我评价
2014/03/03 职场文书
承诺书范文
2014/06/03 职场文书
优秀党员推荐材料
2014/12/18 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
2015年行政人事部工作总结
2015/05/13 职场文书
六五普法心得体会2016
2016/01/21 职场文书
解决Mysql的left join无效及使用的注意事项说明
2021/07/01 MySQL