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 相关文章推荐
JavaScript中的面向对象介绍
Jun 30 Javascript
JavaScript开发者必备的10个Sublime Text插件
Feb 27 Javascript
js实现交通灯效果
Jan 13 Javascript
使用Xcache缓存器加速PHP网站的配置方法
Apr 22 Javascript
Vue.js实现实例搜索应用功能详细代码
Aug 24 Javascript
JS非行间样式获取函数的实例代码
Jun 05 Javascript
react.js组件实现拖拽复制和可排序的示例代码
Aug 20 Javascript
js自定义input文件上传样式
Oct 26 Javascript
angular多语言配置详解
May 16 Javascript
vue cli3 配置proxy代理无效的解决
Oct 30 Javascript
ZK中使用JS读取客户端txt文件内容问题
Nov 07 Javascript
如何优化vue打包文件过大
Apr 13 Vue.js
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
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
2010/10/12 PHP
thinkPHP5 tablib标签库自定义方法详解
2017/05/10 PHP
PHP session垃圾回收机制实例分析
2019/06/28 PHP
Array.prototype 的泛型应用分析
2010/04/30 Javascript
javascript 异步页面查询实现代码(asp.net)
2010/05/26 Javascript
jQuery dialog 异步调用ashx,webservice数据的代码
2010/08/03 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
nodejs高大上的部署方式(PM2)
2018/09/11 NodeJs
使用JS获取页面上的所有标签
2018/10/18 Javascript
layui type2 通过url给iframe子页面传值的例子
2019/09/06 Javascript
python中pygame模块用法实例
2014/10/09 Python
Tensorflow 同时载入多个模型的实例讲解
2018/07/27 Python
python selenium爬取斗鱼所有直播房间信息过程详解
2019/08/09 Python
django多种支付、并发订单处理实例代码
2019/12/13 Python
浅谈在JupyterNotebook下导入自己的模块的问题
2020/04/16 Python
python 使用事件对象asyncio.Event来同步协程的操作
2020/05/04 Python
python批量提取图片信息并保存的实现
2021/02/05 Python
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
美国女性奢华品牌精品店:INTERMIX
2017/10/12 全球购物
下面这个程序执行后会有什么错误或者效果
2014/11/03 面试题
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
校园网站的创业计划书范文
2013/12/30 职场文书
工程专业应届生求职信
2014/02/19 职场文书
财务总监管理职责范文
2014/03/09 职场文书
英语一分钟演讲稿
2014/04/29 职场文书
会计专业应届生自荐信
2014/06/28 职场文书
2014年小学数学工作总结
2014/12/12 职场文书
计划生育工作总结2015
2015/04/03 职场文书
求职意向书范本
2015/05/11 职场文书
2015年度个人教学工作总结
2015/05/20 职场文书
2015年青年教师工作总结
2015/05/25 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
apache基于端口创建虚拟主机的示例
2021/04/24 Servers
苹果M1芯片安装nginx 并且部署vue项目步骤详解
2021/11/20 Servers