window对象
window是bom中的顶层对象,其他的对象都是Window的子对象
document对象就是window的子对象
对话框
confim()
1. 值是字符串
2. 值的内容就是提示用户是确定还是否定
3. 返回值是true和false
onload加载事件
- 我们可以给 window 对象或者 <img> 等元素添加 onload 加载事件,表示只有绑定事件的元
素加载完毕才能触发事件,才能执行事件函数。
- 加载完毕:指的是所有HTML结构加载完,并且外部引入资源(js、css、img、
视频)也加载完毕
一个页面只能有一个onload事件
定时器的常见方法
setInterval():循环调用。将一段代码,每隔一段时间执行一次。(循环执行)
setTimeout():延时调用。将一段代码,等待一段时间之后再执行。(只执行一次)
备注:在实际开发中,二者是可以根据需要,互相替代的。
延时器
是window下面的一个方法
语法 ;
window.setTimeout(func,time);
参数
-
setTimeout()
:延时调用。将一段代码,等待一段时间之后再执行。(只执行一次)参数:
参数1:回调函数,该函数会每隔一段时间被调用一次。
参数2:每次调用的间隔时间,单位是毫秒。
返回值:返回一个Number类型的数据。这个数字用来作为定时器的唯一标识,方便用来清除定时器。
- 1 第一种写法
//调用函数 延迟时间
window.setTimeout(function () {}, 3000);
- 2 第二种写法
function mo() {
console.log("时间到了");
}
// 第一个是函数名 后面是延时时间
setTimeout(mo, 3000);
清除延时器
window.clearTimeout()
// 清除定时器
bt.addEventListener("click", () => {
//括号里面是函数名
clearTimeout(mo);
});
代码举例:
const timer = setTimeout(function() {
console.log(1); // 3秒之后,再执行这段代码。
}, 3000);
clearTimeout(timer);
代码举例:(箭头函数写法)
setTimeout(() => {
console.log(1); // 3秒之后,再执行这段代码。
}, 3000);
setInterval() 的使用
setInterval()
:循环调用。将一段代码,每隔一段时间执行一次。(循环执行)
参数:
参数1:回调函数,该函数会每隔一段时间被调用一次。
参数2:每次调用的间隔时间,单位是毫秒。
返回值:返回一个Number类型的数据。这个数字用来作为定时器的唯一标识,方便用来清除定时器
定义定时器
方式一:匿名函数
每间隔一秒,将 数字 加1:
let num = 1;
setInterval(function () {
num ++;
console.log(num);
}, 1000);
方式二:
每间隔一秒,将 数字 加1:
setInterval(fn,1000);
function fn() {
num ++;
console.log(num);
}
清除定时器
定时器的返回值是作为这个定时器的唯一标识,可以用来清除定时器。具体方法是:假设定时器setInterval()的返回值是参数1
,那么clearInterval(参数1)
就可以清除定时器。
setTimeout()的道理是一样的。
代码举例:
<script>
let num = 1;
const timer = setInterval(function () {
console.log(num); //每间隔一秒,打印一次num的值
num ++;
if(num === 5) { //打印四次之后,就清除定时器
clearInterval(timer);
}
}, 1000);
</script>
简单运动
制作方法
- 制作方法:通过定时器,实现每隔一个极短的时间(50-100 毫秒左右),执行函数,函数
内部让运动的属性值发生变化
一.简单运动小案例
点击按钮,元素向右移动,每一次移动运动10px
//获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function () {
//添加定时器,每隔几秒移动多少
//信号亮
var lf = 0;
setInterval(function () {
lf += 10;
//将最新的值赋值给元素
div.style.left = lf + 'px';
}, 1000)
}
!!! 注意:在书写是,被移动的属性是需要决定位,通过不断改变left的值,实现向右移动
- 全局变量,存储left的属性值,会每一次发生变化。信号亮,这个值控制某一个属性值的变化,每一次发生变化,就会重新赋值给元素
- 信号亮的值不许是于被移动的元素的初始值保持一致,不然会出现跳动效果
提高运动速度
-
缩短运动时间,增加每秒移动的次数
- 这里指的是定时器后面的秒数,如果改变毫秒数,调制小的值,就可以实现快速运动
-
加大步长,让每一次移动的距离增加
- 这里指的是,每一次元素移动的距离增加,实现变快的效果
setInterval(function () {
lf += 10;
//将最新的值赋值给元素
div.style.left = lf + 'px';
}, 1000)
- 这里的lf+=10也就是说,10是移动的距离,每一次增加10px,要是希望变快,可以调节移动的距离
清除定时器的问题
1、多次点击开始,会造成加速
原因:点击多次开始,相当于执行了多次事件函数,定时器出现多次,如果不清除,定时器依旧存在,每一次定时器出现,假如说每一次移动的步长是10,当多次执行事件函数,相当于不段在增加,不指是10,开几次就会加上多少
2、多次点击开始,不能够再停止
原因:每一次的开启定时器,timer变量都会指向新的值,只是清除了最后一次的定时器,而其他开启的定时器并没有被清除,所以多次点击停止,并没有起到停止的效果
解决方法(设表先关)
每次开启新定时器之前,都清除一次前面的定时器,保证只有一个定时器是好用的,其他的定时器会被清除掉
//获取元素
var btn = document.querySelector('.btn1');
var div = document.querySelector('div');
var btn2 = document.querySelector('.btn2');
var timer;
btn.onclick = function () {
//添加定时器,每隔几秒移动多少
//信号亮
var lf = 0;
//每一次执行之前,先清除定时器;
clearInterval(timer);
timer = setInterval(function () {
lf += 10;
div.style.left = lf + 'px';
}, 100)
}
btn2.onclick = function () {
clearInterval(timer);
}
在外部定义timer变量,用开接收里面的定时器,因为函数作用域的不同,所以需要定义变量进行接收,一边后面清除
二、拉终停表
问题:想要元素移动指定的位置,例如让元素停止在 500px 的位置
如果步长设置的不合理,停止的位置可能不是正好在 500 处。
//获取元素
var btn = document.querySelector('.btn1');
var div = document.querySelector('div');
var btn2 = document.querySelector('.btn2');
var timer;
btn.onclick = function () {
//添加定时器,每隔几秒移动多少
//信号亮
var lf = 0;
//每一次执行之前,先清除定时器;
clearInterval(timer);
timer = setInterval(function () {
lf += 10;
//判断元素是否到达指定位置,清除定时器
if(lf >=500){
clearInterval(timer);
}
div.style.left = lf + 'px';
}, 100)
}
btn2.onclick = function () {
clearInterval(timer);
}
变量自加的时候,就判断,元素是否移动到指定的位置
解决办法,直接将元素到达的位置,直接给变量赋值过去,在定时其内部用if语句进行判断,将元素的位置强行设置到500px的位置,并且停止定时器
//获取元素
var btn = document.querySelector('.btn1');
var div = document.querySelector('div');
var btn2 = document.querySelector('.btn2');
var timer;
btn.onclick = function () {
//添加定时器,每隔几秒移动多少
//信号亮
var lf = 0;
//每一次执行之前,先清除定时器;
clearInterval(timer);
timer = setInterval(function () {
lf += 10;
//判断元素是否到达指定位置,清除定时器
if(lf >=500){
//强制设置变量的值为500
lf = 500;
clearInterval(timer);
}
div.style.left = lf + 'px';
}, 100)
}
btn2.onclick = function () {
clearInterval(timer);
}
三、步标整除
问题:在规定时间内让元素走到规定的结束位置,时间间隔可以更改,
例如:让元素在 2 秒钟内,left 属性从 0 走到 500px.
- 总距离:结束位置 - 初始位置
- 总次数:总时长 / 时间间隔
- 步长 = (总距离 / 总次数) / (总时长 / 时间间隔)
var btn = document.querySelector('.btn1');
var div = document.querySelector('div');
//定义信号量(元素初始位置,后面通过定时器每一次 += 移动的距离)
var newLeft = 0;
//定义元素结束位置(定义变量的目的是为了以后更改,可以直接改一个值,后面全部计算也一起改)
var endLeft = 500px;
//定义存储定时器的变量
var timer;
//定义总的移动时间
var time = 2000; //2s
//定义时间间隔
var interval = 50;
//运动的次数
var maxcount = time / interval;
//定义一个记录移动次数的变量,每一次移动记录下来,作为判断条件
var count = 0;
//定义接收总步长的变量,并且计算出总步长是多少
var step = (endLeft - newLeft) / maxcount;
//给按钮添加点击事件
btn.onclick = function(){
//定时器
timer = setInterval(function(){
//初始位置+=步长
newLeft +=step;
//每一次移动进行加1
count++;
//判断当累加的次数大于等于运动总次数,就听话之定时器
if(count >= maxcount){
//拉终停表
newLeft = endLeft;
clearInterval(timer);
}
div.style.left = newLeft + 'px';
},interval)
}
封装动画
简单动画封装
//获取元素属性值 ,window.getComputedStyle(); 获取的值是最终计算出来的值,也就是浏览器里面的值
/**
* 可以打点进行调用
* 参数:要获取元素
* 例如:window.getComputedStyle(div).left
*/
var btn = document.querySelector('button');
var div = document.querySelector('div');
/**思路:多属性运动
* 共同点:总时间,时间间隔自定义
* 不同点:起始位置(同归对象的方式进行传递),结束位置(自定义)
*
* 封装动画函数的参数
* 参数一,元素对象,要运动的标签
* 参数二,结束位置(以对象的形式进行传递参数)传递的参数是对象类型
* 参数三,时间
*/
//函数封装 元素 ,结束位置 , 时间
function animate(ele, end, time) {
//知道结束位置,总时间,时间间隔,缺少起始位置
//起始位置需要根据结束位置提供的属性获取
//起始位置的对象,定义空对象
var start = {};
//对象参数,就是传递的结束位置传递过来的参数,进行遍历,依次添加到对象里
for (var item in end) {
//需要将获取的值进行转换,通过parseFloat,进行取整
//item是结束位置传递过来的属性值 , ele是运动的元素
start[item] = parseFloat(window.getComputedStyle(ele)[item]);
}
//时间间隔
var interval = 50;
//计算步长
var maxcount = time / interval;
//累加器,移动次数
var count = 0;
//对象中的属性,都有自己的步长,可以放在对象里面
var step = {};
//遍历对象,计算结束位置的步长
for (var item in end) {
//步长计算 结束 - 起始位置 / 移动步长
step[item] = (end[item] - start[item]) / maxcount;
}
//定时器
var timer = setInterval(function () {
//移动次数累加
count++;
//让每个属性发生变化,赋值给起始位置中的每一项
for (var item in end) {
start[item] += step[item];
}
//判断运动是否结束
if (count >= maxcount) {
//拉终停表方法
for (var item in end) {
start[item] = step[item];
}
//清除定时器
clearInterval(timer);
}
//赋值给对应的元素属性
for (var item in start) {
ele.style[item] = start[item] + 'px';
}
}, interval)
}
btn.onclick = function () {
animate(div, {
left: 100
}, 2000)
}
简单无缝轮播
实现:两组图片,一组走完另一组接着进行滚动
<body>
<div id="item">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
</div>
</body>
<script>
//获取元素
var item = document.getElementById('item');
var ul = document.querySelector('ul');
//自己进行播放
//起始位置
var nowLeft = 0;
//折返点,也就是说当前面的图片走完了,瞬间1就回到后面的位置,继续向下移动
var back = -1260;
var timer = setInterval(run, 10)
//鼠标移入
ul.onmouseover = function () {
clearInterval(timer);
}
ul.onmouseout = function () {
//先进行清除
clearInterval(timer);
timer = setInterval(run, 10);
}
//鼠标移除
//封装函数,方便调用
function run() {
//让nowLeft自减
nowLeft -= 2;
//判断是否走到了折返点,走到了将前面的拉到后面瞬间切换
if (nowLeft <= back) {
nowLeft = 0;
}
//将值赋值给移动的元素
ul.style.left = nowLeft + 'px';
}
</script>
制作过程
- 获取元素
- 设置信号量,存储元素位置信息的变量 ,
nowLeft = 0
- 折返点,就是当一组图片走到头,走到什么位置,
back = 第一组图片从开始到结束的总距离+边距
- 定义定时器,timer
- 这里内部初始值的运动,因为是向左走,所以是
-=
步长;
- 这里内部初始值的运动,因为是向左走,所以是
- 鼠标移入
- 鼠标移出 (先将定时器清除,然后在开启定时器)
高级无缝轮播
新要求,后期需要增加或者是减少图片
需要更改html解构,更改第一组图片移动到的结束位置总距离
升级部分,自动增加元素,自动获取折返点位置
制作过程
- 获取元素
- 自动获取元素的宽度,计算折返点
- 自动生成一组和原有的图片相同的解构
- 定时器
- 鼠标移入
- 鼠标移除
var nowLeft = 0;
//自动获取元素的宽度 折返点 向左边移动
var back = -item.offsetWidth;
//生成与原来相同的图片解构
ul.innerHtml = ul.innerHtml + ul.innerHtml //原来的解构 = 原来的架构加上原来的解构,也就是两个解构,重新赋值
//定义定时器
var timer = serInterval(run,10)
//定时器函数
function run(){
//信号量向左移动,也就是-=
nowLeft -= 2;
//判断元素移动的距离是否小于或者是等于折返点
if( nowLeft <= back ){
//将nowLeft的值强行拉到0;
nowLeft = 0;
}
//将信号量重新赋值给元素
ul.style.left = nowLeft;
}
完整切图轮播图
制作过程,步骤
- 获取元素
- 左边按钮,上一张
- 右边按钮,下一张
- 圆点事件,点击圆点,切换图片
- 轮播图自动播放
- 鼠标移上轮播图停止
- 鼠标移除,轮播图继续
编程思路,通过信号量,定义全局信号量,在不同的函数内部进行信息传递,让多个事件一起运作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul,
ol {
list-style: none;
}
.carousel {
position: relative;
width: 880px;
height: 550px;
border: 1px solid #333;
margin: 50px auto;
}
.pic li {
position: absolute;
left: 0;
top: 0;
width: 880px;
height: 550px;
display: none;
}
.pic li.current {
display: block;
}
.btn a {
position: absolute;
top: 50%;
width: 80px;
height: 80px;
margin-top: -40px;
background-color: rgba(255, 255, 255, 0.3);
text-decoration: none;
color: #444;
text-align: center;
line-height: 80px;
font-size: 60px;
font-family: "SimSun";
}
.btn .left {
left: 10px;
}
.btn .right {
right: 10px;
}
.btn a:hover {
background-color: rgba(255, 255, 255, 0.7);
}
.sub {
position: absolute;
bottom: 30px;
left: 50%;
width: 200px;
height: 40px;
margin-left: -100px;
border-radius: 20px;
background-color: rgba(255, 255, 255, 0.3);
}
.sub li {
float: left;
width: 20px;
height: 20px;
margin: 10px;
border-radius: 50%;
background-color: #ccc;
cursor: pointer;
}
.sub li.current {
background-color: #0ff;
}
</style>
</head>
<body>
<div class="carousel" id="carousel">
<ul class="pic" id="pic">
<li class="current"><img src="01.jpg" alt=""></li>
<li><img src="02.jpg" alt=""></li>
<li><img src="03.jpg" alt=""></li>
<li><img src="04.jpg" alt=""></li>
<li><img src="05.jpg" alt=""></li>
</ul>
<div class="btn" id="btn">
<a href="javascript:;" class="left" id="leftbtn"><</a>
<a href="javascript:;" class="right" id="rightbtn">></a>
</div>
<ol class="sub" id="sub">
<li class="current"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</body>
<script>
//获取元素
var carousel = document.getElementById('carousel');
var ul = document.getElementById('pic');
var li = ul.children;
var btnLeft = document.getElementById('leftbtn');
var btnRight = document.getElementById('rightbtn');
var ol = document.getElementById('sub');
var olLi = ol.children;
//信号量 存储图片下标
var ind = 0;
//右边按钮
btnRight.onclick = function () {
ind++;
//判读ind是不是超过最大的下标了
if (ind >= li.length) {
ind = 0;
}
qieHuan();
}
//右边按钮
btnLeft.onclick = function () {
//信号量自减少
ind--;
//判读ind是不是超过最大的下标了
if (ind < 0) {
ind = li.length - 1
}
//调用切换函数
qieHuan();
}
//切换函数
function qieHuan() {
//排他思想 将li内部的类名全部清除
for (var i = 0; i < li.length; i++) {
li[i].className = '';
olLi[i].className = '';
}
//保存自己
li[ind].className = 'current';
olLi[ind].className = 'current';
}
//圆点事件 批量添加事件
for (var i = 0; i < olLi.length; i++) {
//存储自己的下标
olLi[i].index = i;
olLi[i].onclick = function () {
ind = this.index;
qieHuan();
}
}
//自动播放
var timer = setInterval(function () {
//事项的功能是相同的 与右边按钮
ind++;
//判读ind是不是超过最大的下标了
if (ind >= li.length) {
ind = 0;
}
qieHuan();
}, 3000);
//鼠标移入
carousel.onmouseover = function () {
clearInterval(timer);
}
carousel.onmouseout = function () {
timer = setInterval(function () {
//事项的功能是相同的 与右边按钮
ind++;
//判读ind是不是超过最大的下标了
if (ind >= li.length) {
ind = 0;
}
qieHuan();
}, 3000);
}
</script>
</html>