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+dom树型菜单类,希望朋友们一起进步
May 03 Javascript
js中巧用cssText属性批量操作样式
Mar 13 Javascript
js实现千分符和保留几位小数的简单实例
Aug 01 Javascript
浅谈Node.js:fs文件系统模块
Dec 08 Javascript
ES6概念 ymbol.for()方法
Dec 25 Javascript
Node.js获取前端ajax提交的request信息
Feb 20 Javascript
javascript 中关于array的常用方法详解
May 05 Javascript
vue使用Axios做ajax请求详解
Jun 07 Javascript
jQuery实现的form转json经典示例
Oct 10 jQuery
Vue 换肤的示例实践
Jan 23 Javascript
vue实现Excel文件的上传与下载功能的两种方式
Jun 28 Javascript
javascript 易错知识点实例小结
Apr 25 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下将图片以二进制存入mysql数据库中并显示的实现代码
2010/05/27 PHP
PHP基础学习小结
2011/04/17 PHP
PHP实现的同步推荐操作API接口案例分析
2016/11/30 PHP
PHP中的正则表达式实例详解
2017/04/25 PHP
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
Laravel5.1 框架路由基础详解
2020/01/04 PHP
php中Swoole的热更新实现代码实例
2021/03/04 PHP
javascript 建设银行登陆键盘
2008/06/10 Javascript
提高javascript效率 一次判断,而不要次次判断
2012/03/30 Javascript
jquery判断元素的子元素是否存在的示例代码
2014/02/04 Javascript
JavaScript学习笔记之定时器
2015/01/22 Javascript
JQuery中serialize()用法实例分析
2015/02/06 Javascript
jQuery版本升级踩坑大全
2016/01/12 Javascript
解析NodeJs的调试方法
2016/12/11 NodeJs
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
js使用原型对象(prototype)需要注意的地方
2017/08/28 Javascript
使用layer弹窗和layui表单实现新增功能
2018/08/09 Javascript
使用Vue-cli3.0创建的项目 如何发布npm包
2019/10/10 Javascript
基于JavaScript实现随机点名器
2021/02/25 Javascript
[44:04]OG vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
wxpython 学习笔记 第一天
2009/02/09 Python
Python使用正则表达式实现文本替换的方法
2017/04/18 Python
Python对List中的元素排序的方法
2018/04/01 Python
django admin 后台实现三级联动的示例代码
2018/06/22 Python
python之信息加密题目详解
2019/06/26 Python
Python实现报警信息实时发送至邮箱功能(实例代码)
2019/11/11 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
唤醒头发毛囊的秘密武器:Grow Gorgeous
2016/08/28 全球购物
秋季运动会稿件
2014/01/30 职场文书
大学校园活动策划书
2014/02/04 职场文书
优秀学生获奖感言
2014/02/15 职场文书
暑期工社会实践报告
2015/07/13 职场文书
早安问候语大全
2015/11/10 职场文书
详解如何在Canvas中添加事件的方法
2021/04/17 Javascript
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python
KVM基础命令详解
2022/04/30 Servers