JavaScript满天星导航栏实现方法


Posted in Javascript onMarch 08, 2018

说明

分享一个满天星导航栏的效果,代码不多,但效果挺好看,先看看效果图吧。

JavaScript满天星导航栏实现方法

解释

实现这个效果,需要掌握的知识不用很多,知道简单的CSS,会用JS 获取元素, 能绑定事件基本就足够了。
好的,我们直接来看代码,注释已经写的很详细了,不想看有注释的,点这里点击预览。

<!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="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >导航1</a></li>
  <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >导航2</a></li>
  <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >导航3</a></li>
  <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >导航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 不理解的点这里:https://codepen.io/FEWY/pen/MQdoWX

总结

实现这个效果,就是做了一个 starrySky对象,定义好一些必须的属性,主要靠 disperse() 和 combine() 两个方法,需要星星分散的时候调用disperse(),需要星星连成线的时候调用combine(),好的就这样了。

Javascript 相关文章推荐
12个非常有创意的JavaScript小游戏
Mar 18 Javascript
基于jquery自定义图片热区效果
Jul 21 Javascript
深入解析contentWindow, contentDocument
Jul 04 Javascript
把jquery 的dialog和ztree结合实现步骤
Aug 02 Javascript
js 通过cookie实现刷新不变化树形菜单
Oct 30 Javascript
javascript处理a标签超链接默认事件的方法
Jun 29 Javascript
Javascript基础教程之比较null和undefined值
May 16 Javascript
JS工作中的小贴士之”闭包“与事件委托的”阻止冒泡“
Jun 16 Javascript
简单谈谈React中的路由系统
Jul 25 Javascript
Vue+mui实现图片的本地缓存示例代码
May 24 Javascript
JavaScript实现的级联算法示例【省市二级联动功能】
Dec 25 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
Oct 27 Javascript
vue.js的computed,filter,get,set的用法及区别详解
Mar 08 #Javascript
详解从买域名到使用pm2部署node.js项目全过程
Mar 07 #Javascript
layui select动态添加option的实例
Mar 07 #Javascript
layui表格checkbox选择全选样式及功能的实例
Mar 07 #Javascript
Bootstrap实现可折叠分组侧边导航菜单
Mar 07 #Javascript
Vue.js+Layer表格数据绑定与实现更新的实例
Mar 07 #Javascript
vue.js 嵌套循环、if判断、动态删除的实例
Mar 07 #Javascript
You might like
腾讯QQ微博API接口获取微博内容
2013/10/30 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP面向对象五大原则之开放-封闭原则(OCP)详解
2018/04/04 PHP
PHP __call()方法实现委托示例
2019/05/20 PHP
分享别人写的一个小型js框架
2007/08/13 Javascript
jQuery hover 延时器实现代码
2011/03/12 Javascript
Javascript中的arguments与重载介绍
2015/03/15 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
vue.js入门(3)——详解组件通信
2016/12/02 Javascript
Bootstrap的modal拖动效果
2016/12/25 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
2017/07/07 Javascript
js中this对象用法分析
2018/01/05 Javascript
解决vue项目使用font-awesome,build后路径的问题
2018/09/01 Javascript
vue父组件触发事件改变子组件的值的方法实例详解
2019/05/07 Javascript
jquery.pager.js分页实现详解
2019/07/29 jQuery
vue组件讲解(is属性的用法)模板标签替换操作
2020/09/04 Javascript
vue将文件/图片批量打包下载zip的教程
2020/10/21 Javascript
Vue中使用JsonView来展示Json树的实例代码
2020/11/16 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
[03:04]DOTA2超级联赛专访ZSMJ “莫名其妙”的逆袭
2013/05/23 DOTA
[01:07:13]TNC vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
[01:52]2020年DOTA2 TI10夏季活动预告片
2020/07/15 DOTA
Python运算符重载详解及实例代码
2017/03/07 Python
用python做一个搜索引擎(Pylucene)的实例代码
2017/07/05 Python
人脸识别经典算法一 特征脸方法(Eigenface)
2018/03/13 Python
详解Python中正则匹配TAB及空格的小技巧
2019/07/26 Python
django序列化时使用外键的真实值操作
2020/07/15 Python
Python基于staticmethod装饰器标示静态方法
2020/10/17 Python
Java面试题:Java类的Main方法如果是Private将会怎么样
2016/08/18 面试题
数据员岗位职责
2013/11/19 职场文书
公司自我介绍演讲稿
2014/08/21 职场文书
劳动争议和解协议书范本
2014/11/20 职场文书
离婚协议书范本(通用篇)
2014/11/30 职场文书
周年庆典答谢词
2015/01/20 职场文书
论语读书笔记
2015/06/26 职场文书
分析设计模式之模板方法Java实现
2021/06/23 Java/Android