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几种形式的树结构菜单
May 10 Javascript
js URL参数的拼接方法比较
Feb 15 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
May 14 Javascript
jQuery模拟新浪微博首页滚动效果的方法
Mar 11 Javascript
使用jquery制作弹出框效果
Apr 03 Javascript
Javascript实现单例模式
Jan 24 Javascript
设计模式中的facade外观模式在JavaScript开发中的运用
May 18 Javascript
jQuery模拟下拉框选择对应菜单的内容
Mar 07 Javascript
详解vue-cli + webpack 多页面实例应用
Apr 25 Javascript
Windows下Node.js安装及环境配置方法
Sep 18 Javascript
修改npm全局安装模式的路径方法
May 15 Javascript
vue+SSM实现验证码功能
Dec 07 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
PHP游戏编程25个脚本代码
2011/02/08 PHP
PHP 第二节 数据类型之字符串类型
2012/04/28 PHP
PHP cdata 处理(详细介绍)
2013/07/05 PHP
CMSPRESS 10行代码搞定 PHP无限级分类2
2018/03/30 PHP
JavaScript 原型与继承说明
2010/06/09 Javascript
解析javascript 浏览器关闭事件
2013/07/08 Javascript
JavaScript编程的10个实用小技巧
2014/04/18 Javascript
运用js教你轻松制作html音乐播放器
2020/04/17 Javascript
自己封装的一个原生JS拖动方法(推荐)
2016/11/22 Javascript
详解微信小程序开发聊天室—实时聊天,支持图片预览
2019/05/20 Javascript
vue-devtools的安装和使用步骤详解
2019/10/17 Javascript
vue中封装axios并实现api接口的统一管理
2020/12/25 Vue.js
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
使用Python编写提取日志中的中文的脚本的方法
2015/04/30 Python
Python制作钉钉加密/解密工具
2016/12/07 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
Python利用Beautiful Soup模块搜索内容详解
2017/03/29 Python
Python实现统计文本文件字数的方法
2017/05/05 Python
简述:我为什么选择Python而不是Matlab和R语言
2017/11/14 Python
Python3多线程操作简单示例
2018/05/22 Python
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
python快速编写单行注释多行注释的方法
2019/07/31 Python
Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答
2019/08/13 Python
python不使用for计算两组、多个矩形两两间的iou方式
2020/01/18 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
2020/03/10 Python
澳大利亚家居用品零售商:Harris Scarfe
2020/10/10 全球购物
一套SQL笔试题
2016/08/14 面试题
会计专业推荐信
2013/10/29 职场文书
商务会议邀请函
2014/01/09 职场文书
专家推荐信模板
2014/05/09 职场文书
长城的导游词
2015/01/30 职场文书
陪护人员误工证明
2015/06/24 职场文书
2016年大学生党员承诺书
2016/03/24 职场文书
因个人工作失误检讨书
2019/06/21 职场文书
sentinel支持的redis高可用集群配置详解
2022/04/01 Redis