该项目是对小米商城系统的模仿,实现了从浏览到登录页面的仿写,是一个动态项目,实现了前端内容的编写
- 效果图
- html代码
- 部分css代码
- 部分js代码
一、效果图
二、HTML代码(部分)
<!-- home 首页导航-->
<div class="home-hero w">
<!-- 轮播图 -->
<div class="slideshow">
<ul class="sli-ul">
<li>
<a href="#">
<img src="./images/img/05.jpg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="./images/img/02.jpeg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="./images/img/03.jpg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="./images/img/04.jpeg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="./images/img/01.jpg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="./images/img/05.jpg" alt="">
</a>
</li>
</ul>
<div class="sli-box">
<a href="javaScript:;"></a>
<a href="javaScript:;"></a>
<a href="javaScript:;"></a>
<a href="javaScript:;"></a>
<a href="javaScript:;"></a>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<!-- sub 下-->
<div class="home-sub clearfix">
<div class="sub-l fl">
<ul class="l-list clearfix">
<li>
<a href="#">
<img src="images/h-01.png" alt=""> 小米秒杀
</a>
</li>
<li>
<a href="#">
<img src="images/h-02.png" alt=""> 企业团购
</a>
</li>
<li>
<a href="#">
<img src="images/h-03.png" alt=""> F码通道
</a>
</li>
<li>
<a href="#">
<img src="images/h-04.png" alt=""> 米粉卡
</a>
</li>
<li>
<a href="#">
<img src="images/h-05.png" alt=""> 以旧换新
</a>
</li>
<li>
<a href="#">
<img src="images/h-06.png" alt=""> 话费充值
</a>
</li>
</ul>
</div>
<div class="sub-r fl">
<ul class="r-list clearfix">
<li class="first">
<a href="#">
<img src="images/r-01.jpg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="images/r-02.jpg" alt="">
</a>
</li>
<li>
<a href="#">
<img src="images/r-03.jpg" alt="">
</a>
</li>
</ul>
</div>
</div>
</div>
<!-- home-main首页主体 -->
<div class="home-main">
<div class="container w">
<!-- 小米秒杀 -->
<div class="home-flashsale">
<div class="box-hd">
<h2 class="title">小米秒杀</h2>
</div>
<div class="box-bd">
<div class="row clearfix">
<div class="flashsale-countdown fl">
<div class="round">
14:00 场
</div>
<img src="images/lightning" alt="">
<div class="desc">
距离结束还有
</div>
<div class="countdown clearfix">
<span></span>
<i>:</i>
<span></span>
<i>:</i>
<span></span>
<i></i>
</div>
</div>
<div class="flashsale-list fl">
<ul class="swiper-wrapper">
<!-- 1 -->
<li class="swiper-slide rainbow-item-1">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-01.webp" alt="小米全面屏电视E32C 灰色 32英寸" width="160" height="160">
</div>
<h3 class="title">小米全面屏电视E32C 灰色 32英寸</h3>
<p class="desc">全面屏设计,人工智能系统</p>
<p class="price">
<span>799</span>元
<del>999元</del>
</p>
</div>
</a>
</li>
<!-- 2 -->
<li class="swiper-slide rainbow-item-2">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-02.webp" alt="米家天然乳胶护颈枕S 灰色" width="160" height="160">
</div>
<h3 class="title">米家天然乳胶护颈枕S 灰色</h3>
<p class="desc">大颗粒释压体验,升级好睡眠</p>
<p class="price">
<span>189</span>元
<del>249元</del>
</p>
</div>
</a>
</li>
<!-- 3 -->
<li class="swiper-slide rainbow-item-3">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-03.webp" alt="Pro 15增强版 i5" width="160" height="160">
</div>
<h3 class="title">Pro 15增强版 i5</h3>
<p class="desc">再次突破强大</p>
<p class="price">
<span>4999</span>元
<del>5899元</del>
</p>
</div>
</a>
</li>
<!-- 4 -->
<li class="swiper-slide rainbow-item-4">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-04.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 5 -->
<li class="swiper-slide rainbow-item-5">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-05.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 6 -->
<li class="swiper-slide rainbow-item-6">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-06.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 7 -->
<li class="swiper-slide rainbow-item-7">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-07.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 8 -->
<li class="swiper-slide rainbow-item-8">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-08.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 9 -->
<li class="swiper-slide rainbow-item-9">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-09.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 10 -->
<li class="swiper-slide rainbow-item-10">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-10.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 11 -->
<li class="swiper-slide rainbow-item-11">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-11.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 12 -->
<li class="swiper-slide rainbow-item-12">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-12.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
<!-- 13 -->
<li class="swiper-slide rainbow-item-13">
<a href="#">
<div class="conter">
<div class="thumb">
<img src="images/com-06.webp" alt="米家黄麻抗菌护脊床垫 1.5米" width="160" height="160">
</div>
<h3 class="title">米家黄麻抗菌护脊床垫 1.5米</h3>
<p class="desc">黄麻偏硬护脊 抗菌防霉无异味</p>
<p class="price">
<span>1249</span>元
<del>1499元</del>
</p>
</div>
</a>
</li>
</ul>
</div>
<div class="swiper-controls">
<span class="swiper-flashsale-prev">
<i class="iconfont btn-left"></i>
</span>
<span class="swiper-flashsale-next">
<i class="iconfont btn-right"></i>
</span>
</div>
</div>
</div>
</div>
二、部分CSS代码(index)
* {
/* 初始化 清除页面元素的内外边距 */
padding: 0;
margin: 0;
/* 盒子模型 */
box-sizing: border-box;
}
body {
/* 弹性布局 让页面元素垂直+水平居中 */
display: flex;
justify-content: center;
align-items: center;
/* 让页面始终占浏览器可视区域总高度 */
height: 100vh;
/* 背景渐变色 */
background: linear-gradient(#141e30, #243b55);
}
.login {
/* 弹性布局 让子元素称为弹性项目 */
display: flex;
/* 让弹性项目垂直排列 原理是改变弹性盒子的主轴方向 父元素就是弹性盒子 现在改变后的主轴方向是向下了 */
flex-direction: column;
/* 让弹性项目在交叉轴方向水平居中 现在主轴的方向是向下 交叉轴的方向是与主轴垂直 交叉轴的方向是向右 */
align-items: center;
width: 400px;
padding: 40px;
background-color: rgba(0, 0, 0, 0.2);
box-shadow: 0 15px 25px rgba(0, 0, 0, 0.4);
}
.login h2 {
color: #fff;
margin-bottom: 30px;
}
.login .login_box {
/* 相对定位 */
position: relative;
width: 100%;
}
.login .login_box input {
/* 清除input框自带的边框和轮廓 */
outline: none;
border: none;
width: 100%;
padding: 10px 0;
margin-bottom: 30px;
color: #fff;
font-size: 16px;
border-bottom: 1px solid #fff;
/* 背景颜色为透明色 */
background-color: transparent;
}
.login .login_box label {
position: absolute;
top: 0;
left: 0;
padding: 10px 0;
color: #fff;
/* 这个属性的默认值是auto 默认是这个元素可以被点击 但是如果我们写了none 就是这个元素不能被点击 , 就好像它可见但是不能用 可望而不可即 */
/* 这个就是两者的区别 */
pointer-events: none;
/* 加个过渡 */
transition: all 0.5s;
}
/* :focus 选择器是当input获得焦点是触发的样式 + 是相邻兄弟选择器 去找与input相邻的兄弟label */
/* :valid 选择器是判断input框的内容是否合法,如果合法会执行下面的属性代码,不合法就不会执行,我们刚开始写布局的时候给input框写了required 我们删掉看对比 当没有required的话input框的值就会被认为一直合法,所以一直都是下方的样式 ,但是密码不会,密码框内的值为空,那么这句话局不合法,required不能为空 当我们给密码框写点东西的时候才会执行以下代码*/
.login .login_box input:focus + label,
.login .login_box input:valid + label {
top: -20px;
color: #03e9f4;
font-size: 12px;
}
.login a {
overflow: hidden;
position: relative;
padding: 10px 20px;
color: #03e9f4;
/* 取消a表现原有的下划线 */
text-decoration: none;
/* 同样加个过渡 */
transition: all 0.5s;
}
.login a:hover {
color: #fff;
border-radius: 5px;
background-color: #03e9f4;
box-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4,
0 0 100px #03e9f4;
}
.login a span {
position: absolute;
}
.login a span:first-child {
top: 0;
left: -100%;
width: 100%;
height: 2px;
/* to right 就是往右边 下面的同理 */
background: linear-gradient(to right, transparent, #03e9f4);
/* 动画 名称 时长 linear是匀速运动 infinite是无限次运动 */
animation: move1 1s linear infinite;
}
.login a span:nth-child(2) {
right: 0;
top: -100%;
width: 2px;
height: 100%;
background: linear-gradient(transparent, #03e9f4);
/* 这里多了个0.25s其实是延迟时间 */
animation: move2 1s linear 0.25s infinite;
}
.login a span:nth-child(3) {
right: -100%;
bottom: 0;
width: 100%;
height: 2px;
background: linear-gradient(to left, transparent, #03e9f4);
animation: move3 1s linear 0.5s infinite;
}
.login a span:last-child {
left: 0;
bottom: -100%;
width: 2px;
height: 100%;
background: linear-gradient(#03e9f4, transparent);
animation: move4 1s linear 0.75s infinite;
}
/* 写一下动画 再坚持一下 视频马上就完了 */
@keyframes move1 {
0% {
left: -100%;
}
50%,
100% {
left: 100%;
}
}
@keyframes move2 {
0% {
top: -100%;
}
50%,
100% {
top: 100%;
}
}
@keyframes move3 {
0% {
right: -100%;
}
50%,
100% {
right: 100%;
}
}
@keyframes move4 {
0% {
bottom: -100%;
}
50%,
100% {
bottom: 100%;
}
}
四、部分js代码(轮播图)
var sli_ul = document.querySelector(".sli-ul"),
sli_li = document.querySelectorAll(".sli-ul li"),
sli_box = document.querySelector(".sli-box"),
left = document.querySelector(".slideshow .left"),
right = document.querySelector(".slideshow .right"),
aAll = document.querySelectorAll(".sli-box a");
//动态生成ul的宽
var liWidth = sli_li[0].offsetWidth;
var ulWidth = liWidth * sli_li.length;
sli_ul.style.width = ulWidth + "px";
//动态使箭头居中
var leftT = (sli_li[0].offsetHeight - left.offsetHeight) / 2;
left.style.top = leftT + "px";
var rightT = (sli_li[0].offsetHeight - right.offsetHeight) / 2;
right.style.top = rightT + "px";
//创建index保存索引
var index = 0;
//设置默认a的样式
aAll[index].style.background = "hsla(0, 0%, 100%, .4)";
aAll[index].style.borderColor = "rgba(0, 0, 0, .4)";
//点击导航索引,让图片切换
for (var i = 0; i < aAll.length; i++) {
aAll[i].num = i;
aAll[i].onclick = function() {
//关闭自动切换的定时器
clearInterval(timer);
//获取点击a的索引,并赋值给index
index = this.num;
setA();
//切换图片
move(sli_ul, "left", -liWidth * index, 150, function() {
});
}
}
//设置一个方法用来设置选中的a
function setA() {
//判断当前图片是否是最后一张
if (index >= sli_ul.children.length - 1) {
sli_ul.style.left = 0;
index = 0;
}
for (var i = 0; i < aAll.length; i++) {
aAll[i].style.background = "";
aAll[i].style.borderColor = "";
//给选中的a设置样式
aAll[index].style.background = "hsla(0, 0%, 100%, .4)";
aAll[index].style.borderColor = "rgba(0, 0, 0, .4)";
//判断当前索引,为2时更换所有a的样式
if (index == 2) {
aAll[i].classList.add("boxA");
} else if (index == 4) {
aAll[i].classList.remove("boxA");
}
}
}
//开启自动切换图片
autoChange();
//定义一个自动切换的定时器标识
var timer;
//创建一个函数,用来开启自动切换图片
function autoChange() {
//开启一个定时器,用来定时去切换图片
timer = setInterval(function() {
index++;
//执行动画,切换图片
move(sli_ul, "left", -liWidth * index, 150, function() {
//修改导航按钮
setA();
});
}, 3000);
}
var flag = true; //定义节流阀
//节流阀用于防止用户滑动的太快,影响视觉,和 banner图的观赏
//这里必须等动画完成后才能进行下一张或者上一张图片的更换
//箭头切换图片功能
left.onclick = function() {
if (flag){
flag=false;
clearInterval(timer)
if (index <= 0) {
index = sli_ul.children.length-1;
sli_ul.style.left = -liWidth * index + "px";
}
index--;
move(sli_ul, "left", -liWidth * index, 150, function() {
flag = true; // 打开节流阀
});
setA();
}
}
//right
right.onclick = function() {
if (flag){
flag=false;
clearInterval(timer);
if (index >= sli_ul.children.length - 1 ) {
index = 0;
sli_ul.style.left = 0;
}
index++; //放后面 先判断再轮播
move(sli_ul, "left", -liWidth * index, 150,function(){
setA();
flag=true;
});
}
}
//页面离开时,暂停定时器 打开时开启
document.addEventListener("visibilitychange", function() {
if (document.hidden === true) { //判断当前窗口的状态
clearInterval(timer);
} else {
//开启自动切换图片
autoChange();
}
});
//鼠标移到ul上关闭定时器
sli_ul.onmouseover = function() {
clearInterval(timer);
}
sli_ul.onmouseout = function() {
clearInterval(timer);
//开启自动切换图片
autoChange();
}
//鼠标移动到左键 右键关闭轮播图
left.onmouseover = function(){
clearInterval(timer);
}
left.onmouseout = function(){
clearInterval(timer);
autoChange();
}
right.onmouseover = function(){
clearInterval(timer);
}
right.onmouseout = function(){
clearInterval(timer);
autoChange();
}
function getStyle(obj, name) { //name传字符串
if (window.getComputedStyle) {
//正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,没有getComputedStyle()方法
return obj.currentStyle[name];
}
}
function move(obj, attr, target, speed, callback) {
//关闭上一个定时器
clearInterval(obj.timer);
//获取元素目前的位置
var current = parseInt(getStyle(obj, attr));
if (current > target) {
speed = -speed;
}
obj.timer = setInterval(function() {
//获取box原来的left值
var oldValue = parseInt(getStyle(obj, attr));
//在旧值得基础上增加
var newValue = oldValue + speed;
if (speed < 0 && newValue < target || speed > 0 && newValue > target) {
newValue = target;
}
//将新值设置给box
obj.style[attr] = newValue + "px";
//当元素移动到执行动画目标时,使其停止执行动画
if (newValue == target) {
clearInterval(obj.timer);
//动画执行完毕,调用回调函数
//有callback执行,没有的话不执行 这样参数可不写
callback && callback();
}
}, 30);
}