JavaScript實現 滿天星 導航欄

說明

分享一個滿天星導航欄的效果,代碼很少,但效果挺好看,先看看效果圖吧。 css

解釋

實現這個效果,須要掌握的知識不用不少,知道簡單的CSS,會用JS 獲取元素, 能綁定事件基本就足夠了。
好的,咱們直接來看代碼,註釋已經寫的很詳細了,不想看有註釋的,點這裏html

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
body {
  background-color: #000;
  /* 防止出現左右的滾動條 */
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.wrapper {
  width: 100%;
  height: 100px;
}
.wrapper .nav {
  list-style: none;
  width: 800px;
  height: 100px;
  padding: 0;
  margin: 0 auto;
}
.wrapper .nav li {
  width: 25%;
  height: 50px;
  float: left;
  margin-top: 25px;
}
.wrapper .nav li a {
  text-decoration: none;
  color: #fff;
  text-align: center;
  line-height: 50px;
  display: block;
  font-size: 20px;
  font-family: "KaiTi";
}

/* 閃爍的星星 的基本樣式 */
.star {
  width: 5px;
  height: 5px;
  background: #fff;
  position: absolute;
  z-index: -1;
}

/*  閃爍動畫,改變透明度  */
@keyframes blink {
  from {
    opacity: 0.2;
  }
  to {
    opacity: 1;
  }
}
</style>
 </head>
 <body>
        <div class="wrapper">
            <ul class="nav">
                <li><a href="#">導航1</a></li>
                <li><a href="#">導航2</a></li>
                <li><a href="#">導航3</a></li>
                <li><a href="#">導航4</a></li>
            </ul>
        </div>
<script>

// 定義一個 starrySky 對象
var starrySky = {
  // 星星的數量
  starNum: 100,

  // 星星的大小,返回一個 2 ~ 12 的隨機數
  starSize () { return 2 + Math.trunc(Math.random() * 10) },

  // 星星的顏色 
  starColor: "#fff",

  // 線的顏色,鼠標進入導航區域,星星會連成一條線
  lineColor: "#fff",

  // 線的高度
  lineHeight: "3px",

  // 星星連成線的時間
  changeTime: "1s",

  // 初始化方法,生成須要的星星,並調用須要的方法
  init () {
    var html = "";
    // 循環生成星星
    for (var i = 0; i < this.starNum; i++) {
      html += "<div class='star' id='star" + i + "'></div>";
    }
    // 拼接到 元素wrapper 中
    document.querySelector(".wrapper").innerHTML += html;

    // 調用 星星分散 的方法
    this.disperse();

    // 調用 星星聚合連成線 的方法 
    this.combine();
  },
  disperse () {
    // 這個that 保存的是 starrySky 對象
    var that = this;

    // 獲取 元素wrapper 的寬度
    var width = document.querySelector('.wrapper').offsetWidth;
    // 獲取 元素wrapper 的高度
    var height = document.querySelector('.wrapper').offsetHeight;
    // 循環,開始在元素wrapper 區域內,生成規定數量的 星星,
    for (var i = 0; i < that.starNum; i++) {
      // 星星的 top值,0 ~ 元素wrapper 高度的隨機數
      var top = Math.trunc(height * Math.random());
      // 星星的 left值,0 ~ 元素wrapper 寬度的隨機數
      var left = Math.trunc(width * Math.random());
      // 星星的大小,調用 starrySky對象的starSize()方法
      var size = that.starSize();
      // 設置分散時每一個星星樣式
      document.querySelector("#star" + i).style.cssText += `
                        top:${top}px;
                        left:${left}px;
                        width:${size}px;
                        height:${size}px;
                        background:${that.starColor};
                        opacity:${Math.random()};
                        border-radius:50%;
                        animation:blink 1s ${Math.random() * 2}s infinite alternate;
                    `;
    }
  },
  combine () {
    // 這個that 保存的是 starrySky 對象
    var that = this;
    // 查找導航欄 裏全部的 a元素,遍歷他們,每一個都綁定上 鼠標進入 和 鼠標移出 事件
    document.querySelectorAll(".nav li a").forEach(function (item) {
      item.addEventListener("mouseover", function (e) {
        // 這裏的this 是觸發事件的當前節點對象,就是鼠標進入時候的 a元素
        // 當前a元素的寬度 / 星星數 = 最後連成線時,星星的寬度
        var width = this.offsetWidth / that.starNum;
        // 遍歷,爲每一個星星修改樣式,開始連成線
        for (var i = 0; i < that.starNum; i++) {
          // 星星的top 值就是,當前a元素的距離頂部的值 + 當前a元素的高度
          var top = this.offsetTop + this.offsetHeight;
          // 星星的left 值就是,當前a元素的距離左邊界的值 + 第i個星星 * 星星的寬度
          var left = this.offsetLeft + i * width
          //  設置每一個星星連成線時的樣式
          document.querySelector("#star" + i).style.cssText += `
                                    width:${width}px;
                                    top:${top}px;
                                    left:${left}px;
                                    height:${that.lineHeight};
                                    background:${that.lineColor};
                                    opacity:1;
                                    border-radius:0;
                                    transition:${that.changeTime};
                                    animation:blink 1s infinite alternate;
                                `;
        }
      });
      // 鼠標移出 調用 星星分散 的方法
      item.addEventListener("mouseout", function () {
        that.disperse();
      });
    }
    );
  },

}
// 調用 starrySky對象的 init方法,實現滿天星效果
starrySky.init();
</script>
 </body>
</html>

注意:若是須要修改樣式,不要把 nav元素 和 nav 裏面的 li元素,給定位了,由於最後線的位置是根據 a元素的 offsetHeight 和 offsetLeft 定位的,若是 nav元素 和 nav 裏面的 li元素 定位了,會改變 a元素的offsetParent元素,位置就不對了。
對offsetHeight、offsetLeft 和 offsetParent 不理解的點這裏前端

總結

實現這個效果,就是作了一個 starrySky對象,定義好一些必須的屬性,主要靠 disperse() 和 combine() 兩個方法,須要星星分散的時候調用disperse(),須要星星連成線的時候調用combine(),好的就這樣了。app

前端簡單說

相關文章
相關標籤/搜索