单击导航时拉伸和展开下划线动画效果

167 阅读1分钟

我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!

前言

使用码上掘金查看实时效果

逻辑

dom和css

页面初始化的dom和css

    <nav>
      <ul>
        <li class="active"><a href="">First</a></li>
        <li><a href="">Second</a></li>
        <li><a href="">Third</a></li>
      </ul>
    </nav>
    body {
      background: #1a1e23;
      font-family: "Lato", sans-serif;
      -webkit-font-smoothing: antialiased;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
    }

    nav {
      position: relative;
      padding-bottom: 12px;
    }
    nav .line {
      height: 2px;
      position: absolute;
      bottom: 0;
      margin: 10px 0 0 0;
      background: #ff1847;
    }
    nav ul {
      padding: 0;
      margin: 0;
      list-style: none;
      display: flex;
    }
    nav ul li {
      margin: 0 40px 0 0;
      opacity: 0.4;
      transition: all 0.4s ease;
    }
    nav ul li:hover {
      opacity: 0.7;
    }
    nav ul li.active {
      opacity: 1;
    }
    nav ul li:last-child {
      margin-right: 0;
    }
    nav ul li a {
      text-decoration: none;
      color: #fff;
      text-transform: uppercase;
      display: block;
      font-weight: 600;
      letter-spacing: 0.2em;
      font-size: 14px;
    }

这个时候没有显示红色的下划线,我们通过初始化的js脚本来实现

image.png

js设置初始化的下划线的宽度和位置

    var nav = $("nav");
    var line = $("<div />").addClass("line");

    line.appendTo(nav);

    var active = nav.find(".active");
    var pos = 0;
    var wid = 0;
    if (active.length) {
      pos = active.position().left;
      wid = active.width();
      line.css({
        left: pos,
        width: wid,
      });
    }

image.png

接下来我们要给dom加上对应的点击事件来实现对应的动画效果

    nav.find("ul li a").click(function (e) {
      e.preventDefault();
      if (!$(this).parent().hasClass("active") && !nav.hasClass("animate")) {
        nav.addClass("animate");

        var _this = $(this);

        nav.find("ul li").removeClass("active");

        var position = _this.parent().position();
        var width = _this.parent().width();

        if (position.left >= pos) {
          line.animate(
            {
              width: position.left - pos + width,
            },
            300,
            function () {
              line.animate(
                {
                  width: width,
                  left: position.left,
                },
                150,
                function () {
                  nav.removeClass("animate");
                }
              );
              _this.parent().addClass("active");
            }
          );
        } else {
          line.animate(
            {
              left: position.left,
              width: pos - position.left + wid,
            },
            300,
            function () {
              line.animate(
                {
                  width: width,
                },
                150,
                function () {
                  nav.removeClass("animate");
                }
              );
              _this.parent().addClass("active");
            }
          );
        }

        pos = position.left;
        wid = width;
      }
    });

animate这个类的是一个判断动画是否在进行中的flag

动画有两种情况

  • 一种是从左往右,比如从first到second或者third
  • 一种是从右往左,从third到second或者third

改变width和left,使用jquery的animatef方法来实行动画效果

总结

今天使用Jquery的一些api来操作dom,实现了简单的动画效果