这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
CSS
定位装饰
作用:实现盒子叠在一起用(浮动是使垂直布局的块级元素变成水平)。可以让盒子始终固定在屏幕的某个位置 使用步骤:
静态定位static
一般不加position都是静态定位
相对定位relative
相对于自己之前的位置移动,注意!原来的位置还是自己的,不会被其他占据,显示模式不会改变,行还是行,块还是块
实现:position:relative(por快捷输入),需要配合方位属性实现移动(水平,垂直各自选一个),不然是不会移动的。 如果left和right都有,以left为准,如果top和botton都有,以top为准
绝对定位absolute
相对于父级进行移动, 原来的位置会被其他盒子占据,显示模式会被改变,变成行内块(一行内可共存,宽高生效) 注意!!!先找已定位的父级,若有,则以它为参照物,若没有,则以浏览器窗口为参照物
子绝父相
就是子级采用绝对定位,父级采用相对定位。
这样做,父级不会脱离标准流,它原来的位置不会被占据,不会导致页面混乱,而子级又可以相对父级移动。
各司其职
结构(html)、表现(css)、行为(js)分离
例子:深夜模式交换
transition(过渡):要过渡的属性 花费时间 运动曲线 何时开始
组件封装
组件是指web页面上一个个包含模板(html)、功能(js)和样式(css)的单元,好的组件具备封装性、正确性、扩展性、复用性
组件设计原则
封装性、正确性、扩展性、复用性
实现组建的步骤
结构设计、展现效果、行为设计
三次重构
插件化、模板化、抽象化(抽象出一个简单的组件框架)
PC端轮播图编写
<style>
.one{
width: 200px;
height: 200px;
background-color: aqua;
position:absolute;
margin-top: 100px;
}
.two{
width: 200px;
height: 200px;
background-color: blueviolet;
position:absolute;
}
</style>
</head>
<body>
<div class="one">
</div>
<button class="four">点击回到400</button>
<button class="eight">点击回到800</button>
<!-- <span class="two"></span> -->
<script>
//动画原理就是
//1.设置一个定时器
//2.写改变位置的函数,也就是它和左边的距离
//定时器每隔一段时间就会调用一次,不断改变左值,达到移动的效果
var one=document.querySelector('.one');
var four=document.querySelector('.four');
var eight=document.querySelector('.eight');
//callback,为回调函数,其实就相当于,把函数当作参数传入当前函数,
//当前函数执行完成后,会实现该函数
function animate(obj,target,callback)
{
//为了防止多次点击产生多个定时器,所以每次先清除以前的定时器
clearInterval(obj.timer)
//注意obj是一个对象,我们可以给这个对象添加属性,所以这里不用var timer,
obj.timer=setInterval(function(){
//加math.ceil是向上取整,这样就能保证,我们到达了指定位置,而不是有小数,和目标距离差一点
var step=(target-obj.offsetLeft)/10
//当我们在多个目标之间移动的时候,由于step会出现负值的情况,
//但是我们是数字大小往上取整,所以需要先判断step大小,正数向上,负数向下取整,才能保证最后我们到达目标位置
step=step>0?Math.ceil(step):Math.floor(step)
if(obj.offsetLeft==target)
{
//停止调用,本质是停止调用计时器
clearInterval(obj.timer);
//回调函数写到定时器结束里面
if(callback)
{
callback();
}
}
obj.style.left=obj.offsetLeft+step+'px';
}, 15);
}
four.addEventListener('click',function(){
animate(one,400,function(){
one.style.backgroundColor='pink'
});
})
eight.addEventListener('click',function(){
animate(one,800);
})
</script>
</body>
</html>
无缝滚动
想要实现播放最后一张图片的时候,回到第一张。所以我们在最后再次添加第一张图片,同时,由于执行速度很快,我们虽然在最后一张,但是我们让其回到了第一张,以此来实现无缝滚动
想要动态生成最后一张图片,并且不会影响到我们小圆圈的生成数量,这里我们在动态创建完成小圆圈之后,克隆第一张图片,添加ul到最后
克隆:cloneNode(),括号里面写true为深克隆,false为浅克隆
两个小bug
①移动方向和右键点击方向不一致,造成图片出现错误
就是要保证点击小圆圈的同时,也注意修改num,num要是当前的角标值—index。因为num在右键点击过程中,控制移动距离,相当于li点击中的index。
②小圆圈应该出现位置和右键点击方向不一致
因为circle控制小圆点变化情况,只有点击右键的时候circle才会变化。所以当我们点击li之后,circle没有变化,会导致小圆圈出现错误。所以我们也需要获取当前li的index,保证小圆圈和li出现对的上,circle=index;
实现自动播放功能
这里相当于自动点击右键,所以我们而没必要重写一遍动画
此时我们使用手动调用右键点击事件——arrowright.click()
节流阀
完成代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播图</title>
<style>
/* 设置外边距为0 */
body,
ul,
ol {
margin: 0;
padding: 0;
}
/* 设置左右箭头格式 */
a {
position: absolute;
text-decoration: none;
font-size: 100px;
/* 这里是层级的意思 */
z-index: 2;
display: none;
}
a:nth-child(1) {
color: bisque;
top: 250px;
left: 0px;
}
a:nth-child(2) {
color: bisque;
top: 250px;
right: 0px;
}
/* 样式为none,就不会出现小圆点,数字等前面的格式 */
ul,
ol {
list-style: none;
}
.focus {
position: relative;
width: 1000px;
height: 600px;
overflow: hidden;
margin: auto;
}
ul {
position: absolute;
width: 500%;
}
img{
float: left;
width: 1000px;
height: 600px;
}
ol {
position: absolute;
bottom: 10px;
left: 104px;
margin: auto;
}
/* 小圆点样式 */
ol li {
float: left;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fff;
margin-left: 5px;
box-sizing: border-box;
padding: 1px soild #fff;
}
/* 当前小圆点样式 */
.current {
background-color: transparent;
border: 2px solid #fff;
}
</style>
</head>
<body>
<div class="focus">
<!-- 左右两个可以切换的箭头 -->
<a href="#" class="arrowleft"><</a>
<a href="#" class="arrowright">></a>
<ul>
<li><img src="./风景图1.jpeg" alt=""></li>
<li><img src="./风景图2.jpeg" alt=""></li>
<li><img src="./风景图3.jpeg" alt=""></li>
<li><img src="./风景图4.jpeg" alt=""></li>
</ul>
<ol>
</ol>
</div>
<script>
//动画函数
function animate(obj,target,callback)
{
clearInterval(obj.timer)
obj.timer=setInterval(function(){
var step=(target-obj.offsetLeft)/10
step=step>0?Math.ceil(step):Math.floor(step)
if(obj.offsetLeft==target)
{
clearInterval(obj.timer);
if(callback)
{
callback();
}
}
obj.style.left=obj.offsetLeft+step+'px';
}, 15);
}
// 获取左右两个箭头
var arrowleft=document.querySelector('.arrowleft');
var arrowright=document.querySelector('.arrowright');
//获取整个大盒子
var focus=document.querySelector('.focus');
var focusWidth=focus.offsetWidth;//盒子长度,方面一会儿实现动画效果
//当鼠标进入的时候就显示左右箭头
focus.addEventListener('mouseenter',function(){
arrowleft.style.display='block';
arrowright.style.display='block';
clearInterval(timer)//停止自动播放
timer=null;//清除定时器
})
//当鼠标离开时,就隐藏左右箭头
focus.addEventListener('mouseleave',function(){
arrowleft.style.display='none';
arrowright.style.display='none';
timer=setInterval(function(){
arrowright.click();
},2000)
})
var ul=focus.querySelector('ul');
var ol=focus.querySelector('ol');
var num=0;
var circle=0
for(var i=0;i<ul.children.length;i++)
{
//创建li
var li=document.createElement('li');
//插入进ol
li.setAttribute('index',i);//添加属性,获得下标,便于计算移动距离
ol.appendChild(li);
//排他思想,使点击的小圆点能够显示不同的样式
li.addEventListener('click',function()
{
for(var i=0;i<ol.children.length;i++)
{
ol.children[i].className='';
}
this.className='current';
//动画效果实现
var index=this.getAttribute('index');
num=index;
circle=index;
//解决上述bug
animate(ul,-index*focusWidth);
})
}
//由于打开页面时,我们就处在第一个界面,所以第一个小圆圈要为current
ol.children[0].className='current';
var first=ul.children[0].cloneNode(true);
ul.appendChild(first);
//右侧点击
var flag=true;//节流阀
arrowright.addEventListener('click',function(){
if(flag)
{
flag=false;
//无缝滚动
if(num==ul.children.length-1)
{
ul.style.left=0;
num=0
}
num++;
circle++;
animate(ul,-num*focusWidth,function(){
flag=true;//打开节流阀,必须在此函数执行完毕之后,才会进行,就相当于必须看完当前动画,才可以进行下一次点击
});
if(circle==4)
{
circle=0;
}
for(var i=0;i<ol.children.length;i++)
{
ol.children[i].className='';
}
ol.children[circle].className='current';
//为什么这里的角标不直接用num,因为num是图片数量,图片数量和小圆点数量不符合。如果我们使用num,在第五张时,由于小圆点不存在此角标,所以所有的小圆点都不会变化下一次num变成了2,所以跳转显示第一张图片时小圆点都一样,只有当又开始第二张,第三张,小圆点才会变成current
}
})
//左侧按钮
arrowleft.addEventListener('click',function(){
if(flag)
{
flag=false;
if(num==0)
{
num=ul.children.length-1;
ul.style.right=-num*focusWidth;
//注意负号,因为是ul左侧距离div的距离
}
num--;
circle--;
animate(ul,-num*focusWidth,function()
{
flag=true;
});
if(circle<0)
{
circle=ol.children.length-1;
}
for(var i=0;i<ol.children.length;i++)
{
ol.children[i].className='';
}
ol.children[circle].className='current';
}
})
//自动播放
var timer=setInterval(function(){
//这里我们发现,相当于自动点击了右侧按钮
arrowright.click();
},2000)
</Script>
</body>
</html>
过程抽象
- 用来处理局部细节控制的一些方法
- 函数式编程思想的基础应用
总结
今天的内容有点难了,有点跟不上,不过对于js代码规范的地方让人醍醐灌顶,因为直接并没有注意到自己写的代码的规范性,只考虑到功能是否实现,对于代码规范,也便于日后的维护,在思考过程当中,也能优化我们的代码