设置浮动,为什么,不能浮动起来,原因,在于,li的父元素的宽度ul此时默认的是outer的宽度,此时outer的宽度就是一个图片的宽度,所以,给li设置浮动,没有效果
下面这个地方,当没有对imgList设置left:0px时,img-list是按照在outer里面的width里面来看位置的,当设置为left:0px时,由于outer为img-list的最小包含块,而且设置了相对定位,所以,img-list就会跑到outer的可见框位置,去紧贴着outer元素可见框的左侧,值得注意的是,此处,虽然,img-list的子元素li,虽然设置了左外边距为10px,但是,并不会出现,像垂直外边距发生重叠了的情况,导致img-list的可见框也会向左移动
下面的图,再次展示了,对于水平方向,并不会像垂直方向那样,发生外边距的重叠
下面展示了结构中的空白对a标签与a标签之间的距离也有影响
这里即使把由于a标签是行内元素,即使把a设置为行内块元素(inline-block),目的是为了给a设置高度和宽度,但是,由于在结构上a标签与a标签有空白,设置为行内块,a并没有脱离文档流,所以a标签与a标签仍然有间距,但是,通过将a设置浮动,或者是开启定位,使其脱离文档流,特别是,此时给a设置为浮动,由于脱离文档流,所以他们之间变的没有空白距离了
此处的居中方式采用的是计算得到的,这样灵活性很高
下面为DOM对象,添加属性,真的牛逼
自写的菜鸡版本
// 点击超链接,切换到指定图片
for(var i = 0; i < navDivSubA.length; i++){
navDivSubA[i].onclick = function(event){
event = event || window.event;
for(var j = 0; j < navDivSubA.length; j++){
if(event.target == navDivSubA[j]){//或者是利用this == navDivSubA
imgList.style.left = j * -520 + "px";
}
}
}
}
视频中的牛逼版本
for(var i = 0; i < navDivSubA.length; i++){
navDivSubA[i].number = i;
navDivSubA[i].onclick = function(){
imgList.style.left = this.number * -520 + "px";
}
}
上面采用的方法是为DOM对象添加属性,然后通过this的使用,利用DOM对象的属性,来获取点击的a标签所处的下标,牛逼
下面是实现,点击某个a后,这个被点击的a变黑,其它的变红,这个逻辑,自己想的第一种方式是记录上一次点击的a,当这次点击另一个a发生时,把上一个a对应的背景颜色做修改,但是,显然这个,不好实现。 方法二:采取构建设置setA()的函数,然后第一步是全部红,第二部点击的变黑
上面要设置空串,这里的空串,实际上是指,将a标签的背景颜色设置为原来的值,也就是第一个红方框的设定值,注意,这里的第二个红方框的选择器权重其实是大于第一个红色方框的选择器的权重的,但是,这里的空串,并不是代表恢复到第二个红色方框的背景样式
自己最开始写的轮播图,很LOW,图片的切换,没有形成一种过渡的效果,而是突变的,(主要原因是,是通过得到图片的索引值之后,直接改变imgList的left)
<!DOCTYPE html>
<html lang="zh">
<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>slideshow</title>
<style>
* {
margin: 0px;
padding: 0px;
}
#outer {
width: 520px;
height: 333px;
background-color: #bfa;
padding: 10px 0px;
margin: 50px auto;
/* 这个图片对齐的问题还没解决 */
/* vertical-align:center; */
overflow: hidden;
position: relative;
}
#imgList {
/* width: 2600px; */
position: absolute;
list-style: none;
}
#imgList li {
margin: 0px 10px;
float: left;
/* 注意这个地方,不是给li开启定位,如果给li开启定位会出现,
那么就会出现层级的问题,就需要调整z-index来解决问题,这个比较麻烦
,所以,此处应该给imgList开启绝对定位 */
/* position:absolute; */
}
#navDiv {
position: absolute;
bottom: 15px;
/* left:0px;
right:0px;
margin:0 auto; */
}
#navDiv a {
float: left;
width: 20px;
height: 20px;
background-color: red;
margin: 0px 5px;
opacity: 0.5;
/* 兼容IE8,但是chrome里面就又不行了*/
/* filter:alpha(opacity = 50); */
}
#navDiv a:hover{
background-color:black;
}
</style>
<script>
window.onload = function () {
// 创建slidesshow下标变量
var index = 0;
// 获取样式的函数
function getStyle(obj, name) {
if (window.getComputedStyle) {
// console.log("执行了吗?");
return getComputedStyle(obj, null)[name];
} else {
return obj.currentStyle[name];
}
}
// 创建slidesshow函数
function slidesShowFun(){
navDivSubA[index].style.backgroundColor = "red";
index++;
if(index > imgArr.length -1){
index = 0;
}
imgList.style.left = index * -520 + "px";
navDivSubA[index].style.backgroundColor = "black";
}
// 获取imgList
var imgList = document.getElementById("imgList");
// 设置存放图片的数组
imgArr = ["./轮播图图片/1.jpg", "./轮播图图片/2.jpg", "./轮播图图片/3.jpg", "./轮播图图片/4.jpg", "./轮播图图片/5.jpg"];
imgList.style.width = imgArr.length * 520 + "px";
// 获取outer
var outer = document.getElementById("outer");
// alert(outer);
// 获取navDiv
var navDiv = document.getElementById("navDiv");
var left = (outer.offsetWidth - navDiv.offsetWidth) / 2;
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth) / 2 + "px";
//定时调用slidesshow函数
setInterval(slidesShowFun, 2000);
// 获取navDiv下面所有的a
var navDivSubA = navDiv.children;
// 默认第一个a的背景颜色先为黑色
navDivSubA[index].style.backgroundColor = "black";
// 兼容opacity的处理
/* function compatibleOpacity(){
if(this.filter){
this.style.filter = alpha(opacity = 50);
}else{
this.style.opacity = 0.5;
}
}
compatibleOpacity.call(navDivSubA); */
}
</script>
</head>
<body>
<div id="outer">
<ul id="imgList">
<li><img src="./轮播图图片/1.jpg" alt=""></li>
<li><img src="./轮播图图片/2.jpg" alt=""></li>
<li><img src="./轮播图图片/3.jpg" alt=""></li>
<li><img src="./轮播图图片/4.jpg" alt=""></li>
<li><img src="./轮播图图片/5.jpg" alt=""></li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
</body>
</html>
但是,视频中,在切换图片的过程中,利用Js中的定时函数setInterval函数,通过定时调用,来修改left的值,这样就形成了类似css中的transition的效果,注意(视频中实现切换的动态变化,而不是瞬间变化,利用的是tools这个封装好的函数),思考下,当时定时函数中的定时时间设置太大和太小的效果
</font color=“red”>视频中的自动播放,其实也是采用的定时函数来处理的
视频中,自动播放的效果那里,为了处理不好的体验感,通过两步处理,第一:在最后加上第一张图片 第二:利用自己写的很low的自动播放的思想,也就是直接切换,不是过切换图片,来处理体验感不好的感觉,主要是利用人眼的视觉暂留,以及move中的那个setInterval中的定时时间(30ms),与快速切换相比,这个时间远远短于30ms,并且利用最后一张图片和第一张图片长的一样,以及视觉暂留,完美地解决了体验感的问题
此例子中,个人觉得值得学习的几点有
第一:什么时候用全局变量???
答:一般,这个变量在不同的函数域,甚至是函数域或者是全局均需要用到的时候,一般选择全局变量
第二: 什么时候使用“对象.属性名”或者是“对象[变量名]”来保存某个值比较好呢???这个相对于全局变量有什么优势呢?
答:全局变量虽然有全局作用域范围的优势,但是,这意味它修改的是同一个值,但是,我们,比如定时器使用中的那个,龟兔赛跑的例子中,利用不同的按钮去控制不同的盒子移动,如果用同一个全局变量来保存,会造成一个盒子开启时,另外一个盒子就会停止运动,为了解决这个问题,可以采用以下两种方法,分别设置全局变量(也就是两个全局变量,来接受setInterval的值) 方法二:使用对象.属性名或者是对象[变量]的方式来保存,使用第二种方式,在某些情况下,也可以达到全局访问的效果,而且此“js实现轮播图的的案列中,在给a绑定响应函数时,为了获得对应的索引,就采用了“对象.属性名”的方式保存索引值”
第三,在创建函数时,形参位置,可以设置多余实参的变量,用来解决,当实参少于形参个数时,按照实际需要,是否使用形参中多余的变量,里面用到的处理方式如下:
上面利用了"&&"找false的特点
第四: 此次,js实现轮播图的效果中,全局变量index全局使用时,在很多函数域中,尽量少用index,以免引起冲突,带来后患
之所以这么说,是因为,怕有影响,总结就是,当一个全局变量在函数域中时,尽量在该函数域中,不要基于使用该全局变量来获取其它的值,比如:上图中的index是全局变量,在上面函数中,for循环遍历时,不要写成var index, 但是,当函数域范围内,我们不涉及到全局变量的使用时,仍然可以使用和全局变量同名的局部变量进行for循环的遍历或者是其它的操作
第五:熟练知道此练习中“js实现轮播图的思路”,以及还有哪些实现轮播的思路,以及tools工具中的封装的函数的target和speed很人性化设计的一点
tools如下所示
//尝试创建一个可以执行简单动画的函数
/*
* 参数:
* obj:要执行动画的对象
* attr:要执行动画的样式,比如:left top width height
* target:执行动画的目标位置
* speed:移动的速度(正数向右移动,负数向左移动)
* callback:回调函数,这个函数将会在动画执行完毕以后执行
*/
function move(obj, attr, target, speed, callback) {
//关闭上一个定时器
clearInterval(obj.timer);
//获取元素目前的位置
var current = parseInt(getStyle(obj, attr));
//判断速度的正负值
//如果从0 向 800移动,则speed为正
//如果从800向0移动,则speed为负
if(current > target) {
//此时速度应为负值
speed = -speed;
}
//开启一个定时器,用来执行动画效果
//向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
obj.timer = setInterval(function() {
//获取box1的原来的left值
var oldValue = parseInt(getStyle(obj, attr));
//在旧值的基础上增加
var newValue = oldValue + speed;
//判断newValue是否大于800
//从800 向 0移动
//向左移动时,需要判断newValue是否小于target
//向右移动时,需要判断newValue是否大于target
if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
//将新值设置给box1
obj.style[attr] = newValue + "px";
//当元素移动到0px时,使其停止执行动画
if(newValue == target) {
//达到目标,关闭定时器
clearInterval(obj.timer);
//动画执行完毕,调用回调函数
callback && callback();
}
}, 30);
}
/*
* 定义一个函数,用来获取指定元素的当前的样式
* 参数:
* obj 要获取样式的元素
* name 要获取的样式名
*/
function getStyle(obj, name) {
if(window.getComputedStyle) {
//正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,没有getComputedStyle()方法
return obj.currentStyle[name];
}
}
第六:变量除了有保存值好处外,利用变量随时保存记录一个值,以便于后面利用
第七:对于样式的设置,当点击一个a时,其它的a变为红色,被点击的a变为黑色,采取的做法是,利用setA先全红,后其中一个变黑的思路,而不是让之前变黑的a,变红
源代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
/*
* 设置outer的样式
*/
#outer{
/*设置宽和高*/
width: 520px;
height: 333px;
/*居中*/
margin: 50px auto;
/*设置背景颜色*/
background-color: greenyellow;
/*设置padding*/
padding: 10px 0;
/*开启相对定位*/
position: relative;
/*裁剪溢出的内容*/
overflow: hidden;
}
/*设置imgList*/
#imgList{
/*去除项目符号*/
list-style: none;
/*设置ul的宽度*/
/*width: 2600px;*/
/*开启绝对定位*/
position: absolute;
/*设置偏移量*/
/*
* 每向左移动520px,就会显示到下一张图片
*/
left: 0px;
}
/*设置图片中的li*/
#imgList li{
/*设置浮动*/
float: left;
/*设置左右外边距*/
margin: 0 10px;
}
/*设置导航按钮*/
#navDiv{
/*开启绝对定位*/
position: absolute;
/*设置位置*/
bottom: 15px;
/*设置left值
outer宽度 520
navDiv宽度 25*5 = 125
520 - 125 = 395/2 = 197.5
* */
/*left: 197px;*/
}
#navDiv a{
/*设置超链接浮动*/
float: left;
/*设置超链接的宽和高*/
width: 15px;
height: 15px;
/*设置背景颜色*/
background-color: red;
/*设置左右外边距*/
margin: 0 5px;
/*设置透明*/
opacity: 0.5;
/*兼容IE8透明*/
filter: alpha(opacity=50);
}
/*设置鼠标移入的效果*/
#navDiv a:hover{
background-color: black;
}
</style>
<!--引用工具-->
<script type="text/javascript" src="js/tools.js"></script>
<script type="text/javascript">
window.onload = function(){
//获取imgList
var imgList = document.getElementById("imgList");
//获取页面中所有的img标签
var imgArr = document.getElementsByTagName("img");
//设置imgList的宽度
imgList.style.width = 520*imgArr.length+"px";
/*设置导航按钮居中*/
//获取navDiv
var navDiv = document.getElementById("navDiv");
//获取outer
var outer = document.getElementById("outer");
//设置navDiv的left值
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth)/2 + "px";
//默认显示图片的索引
var index = 0;
//获取所有的a
var allA = document.getElementsByTagName("a");
//设置默认选中的效果
allA[index].style.backgroundColor = "black";
/*
点击超链接切换到指定的图片
点击第一个超链接,显示第一个图片
点击第二个超链接,显示第二个图片
* */
//为所有的超链接都绑定单击响应函数
for(var i=0; i<allA.length ; i++){
//为每一个超链接都添加一个num属性
allA[i].num = i;
//为超链接绑定单击响应函数
allA[i].onclick = function(){
//关闭自动切换的定时器
clearInterval(timer);
//获取点击超链接的索引,并将其设置为index
index = this.num;
//切换图片
/*
* 第一张 0 0
* 第二张 1 -520
* 第三张 2 -1040
*/
//imgList.style.left = -520*index + "px";
//设置选中的a
setA();
//使用move函数来切换图片
move(imgList , "left" , -520*index , 20 , function(){
//动画执行完毕,开启自动切换
autoChange();
});
};
}
//开启自动切换图片
autoChange();
//创建一个方法用来设置选中的a
function setA(){
//判断当前索引是否是最后一张图片
if(index >= imgArr.length - 1){
//则将index设置为0
index = 0;
//此时显示的最后一张图片,而最后一张图片和第一张是一摸一样
//通过CSS将最后一张切换成第一张
imgList.style.left = 0;
}
//遍历所有a,并将它们的背景颜色设置为红色
for(var i=0 ; i<allA.length ; i++){
allA[i].style.backgroundColor = "";
}
//将选中的a设置为黑色
allA[index].style.backgroundColor = "black";
};
//定义一个自动切换的定时器的标识
var timer;
//创建一个函数,用来开启自动切换图片
function autoChange(){
//开启一个定时器,用来定时去切换图片
timer = setInterval(function(){
//使索引自增
index++;
//判断index的值
index %= imgArr.length;
//执行动画,切换图片
move(imgList , "left" , -520*index , 20 , function(){
//修改导航按钮
setA();
});
},3000);
}
};
</script>
</head>
<body>
<!-- 创建一个外部的div,来作为大的容器 -->
<div id="outer">
<!-- 创建一个ul,用于放置图片 -->
<ul id="imgList">
<li><img src="img/1.jpg"/></li>
<li><img src="img/2.jpg"/></li>
<li><img src="img/3.jpg"/></li>
<li><img src="img/4.jpg"/></li>
<li><img src="img/5.jpg"/></li>
<li><img src="img/1.jpg"/></li>
</ul>
<!--创建导航按钮-->
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
</body>
</html>
自己仿写如下
<!DOCTYPE html>
<html lang="zh">
<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>slideshow_2</title>
<style>
* {
margin: 0px;
padding: 0px;
}
#outer {
width: 520px;
height: 333px;
background-color: #bfa;
padding: 10px 0px;
margin: 50px auto;
/* 这个图片对齐的问题还没解决 */
/* vertical-align:center; */
overflow: hidden;
position: relative;
}
#imgList {
/* width: 2600px; */
position: absolute;
left: 0px;
}
#imgList li {
margin: 0px 10px;
float: left;
list-style: none;
/* 注意这个地方,不是给li开启定位,如果给li开启定位会出现,
那么就会出现层级的问题,就需要调整z-index来解决问题,这个比较麻烦
,所以,此处应该给imgList开启绝对定位 */
/* position:absolute; */
}
#navDiv {
position: absolute;
bottom: 15px;
/* left:0px;
right:0px;
margin:0 auto; */
}
#navDiv a {
float: left;
width: 20px;
height: 20px;
background-color: red;
margin: 0px 5px;
opacity: 0.5;
/* 兼容IE8,但是chrome里面就又不行了*/
/* filter:alpha(opacity = 50); */
}
#navDiv a:hover {
background-color: black;
}
</style>
<!-- 引入工具 -->
<script src="./tools.js"></script>
<script>
window.onload = function () {
// 定义自动播放定时器的标识
var timer;
// 创建slidesshow下标变量
var index = 0;
// 获取imgList
var imgList = document.getElementById("imgList");
// 设置存放图片的数组
imgArr = ["./轮播图图片/1.jpg", "./轮播图图片/2.jpg", "./轮播图图片/3.jpg", "./轮播图图片/4.jpg", "./轮播图图片/5.jpg", "./轮播图图片/1.jpg"];
imgList.style.width = imgArr.length * 520 + "px";
// 获取outer
var outer = document.getElementById("outer");
// alert(outer);
// 获取navDiv
var navDiv = document.getElementById("navDiv");
var left = (outer.offsetWidth - navDiv.offsetWidth) / 2;
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth) / 2 + "px";
// 获取navDiv下面所有的a
var navDivSubA = navDiv.children;
// 默认第一个a的背景颜色先为黑色
navDivSubA[index].style.backgroundColor = "black";
// 点击超链接,切换到指定图片
/* for(var i = 0; i < navDivSubA.length; i++){
navDivSubA[i].onclick = function(event){
event = event || window.event;
for(var j = 0; j < navDivSubA.length; j++){
if(event.target == navDivSubA[j]){//或者是利用this == navDivSubA
imgList.style.left = j * -520 + "px";
}
}
}
} */
for (var i = 0; i < navDivSubA.length; i++) {
navDivSubA[i].number = i;
navDivSubA[i].onclick = function () {
clearInterval(timer);
// imgList.style.left = this.number * -520 + "px";
index = this.number
// 修改导航点
setA();
move(imgList, "left", index * -520, 10, function () {
// 重新开启自动播放
autoChange();
});
}
}
autoChange();
// 创建设置a背景颜色的函数
function setA() {
// 判断索引处是不是最后一张图片
if (index >= imgArr.length - 1) {
index = 0;
// 将此时的最后一张图片,瞬间换成第一张图片(利用了最后一张图片和第一张图片是一摸一样的特点,这样,就看不出来我们在换图片的操作)
imgList.style.left = "0px";
}
for (var i = 0; i < navDivSubA.length; i++) {
/* 这个下面,如果是写"red",由于是通过js设置的样式,所以设置到内联样式部分了,
于是,造成在触发该函数后,上面的hover就不起作用了,因此,这里可以修改如下 */
// 修改前
// navDivSubA[index].style.backgroundColor = "red";
// 修改后(设置为空串)
navDivSubA[i].style.backgroundColor = "";
}
navDivSubA[index].style.backgroundColor = "black";
}
// 创建自动切换图片的函数
function autoChange() {
timer = setInterval(function () {
index++;
console.log(index);
/* if(index > imgArr.length - 1){
console.log("执行循环了吗???");
index = 0;
} */
//索引的越界判断
index %= imgArr.length;
move(imgList, "left", index * -520, 10, function () {
// 修改导航点
setA();
});
}, 3000);
}
}
</script>
</head>
<body>
<div id="outer">
<ul id="imgList">
<li><img src="./轮播图图片/1.jpg" alt=""></li>
<li><img src="./轮播图图片/2.jpg" alt=""></li>
<li><img src="./轮播图图片/3.jpg" alt=""></li>
<li><img src="./轮播图图片/4.jpg" alt=""></li>
<li><img src="./轮播图图片/5.jpg" alt=""></li>
<li><img src="./轮播图图片/1.jpg" alt=""></li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
</body>
</html>