po主比較懶,昨天出去玩耍,所以前天的筆記沒有來得及整理。現在發上來吧。
這一章主要是關于計時器的學習,其中包括set Interval與setTimeout,以及利用這兩個方法實現的一些動畫小案例。
話不多說,直接上筆記
1.定時器
1.1 通過js,我們有能力做到在一個設定的時間間隔之后來執行一段程序,而不是在函數調用之后立即執行,我們稱之為計時事件
1.2 定時器就是在指定時間間隔后來執行函數。
setTimeout:setTimeout(參數1,參數2);延時調用,只執行一次
參數1:函數、函數名稱;
參數2:指定時間(單位是毫秒)1s==1000ms
function print(){console.log("打印了")}
setTimeout(print,1000);
setInterval:setInterval(參數1,參數2);重復執行
參數1:函數、函數名稱;
參數2:指定時間,單位是毫秒,1s===1000ms
function print(){console.log("打印了")}
var timer = setInterval(print,1000);
停止計時器
clearInterval(timer);
1.3 關于計時器的小練習,可以參考W3C
2.封裝使用ID獲取標簽的方法###
包括但不局限于ID的封裝,前面的筆記中有一個關于利用class屬性來獲取指定標簽的封裝,有需要的童鞋也可以去看看。
封裝:function $(id){return document.getElementById(id)};
使用:var box = $("box");
3.動畫###
3.1 定時器在使用之前必須先停止計時器
3.2 勻速動畫
利用計時器改變目標標簽的位置,以步長為屬性進行累加直到目標標簽達到指定位置
CSS代碼:
*{
margin: 0;
padding: 0;
}
#box{
width: 100px;
height: 100px;
background: #000;
}
HTML代碼:
<button id="btn">點擊按鈕開始勻速動畫</button>
<div id="box"></div>
JS代碼:
function $(id){return document.getElementById(id);}
var btn = $("btn"),div = $("box");
var step = 0,target = 600,timer = null;
btn.onclick = function () {
clearInterval(timer);
timer = setInterval(function () {
step+=2;
if(step>=600){
step=600;
clearInterval(timer);
}
div.style.marginLeft=step+"px";
},10)
}
3.3 減速動畫
運動學公式
var leader = 0;
var target = 600;
var sport = (target - leader) / 10;
leader = leader+sport; //leader+=sport;
在上面的代碼中,我們如果打印一下sport的值,將會發現sport是一個由大逐漸變小的過程。就達到了減速動畫的效果。下面我們來看一段demo:
CSS代碼:
*{
margin: 0;
padding: 0;
}
#box{
width: 100px;
height: 100px;
background: greenyellow;
}
HTML代碼:
<button id="btn">點擊按鈕開始減速運動</button>
<div id="box"></div>
JS代碼:
function $(id){return document.getElementById(id);}
var btn = $("btn"),box = $("box");
var target = 600,leader = 0,timer =null;
btn.onclick= function () {
clearInterval(timer);
timer = setInterval(function () {
if(Math.round(leader)==600){
clearInterval(timer);
leader=600;
}
leader+=(target-leader)/50;
box.style.marginLeft = leader+"px";
},30);
}
當然,細心的童鞋已經發現了,雖然leader的值雖然無限接近于我們的目標值target,但由于每次目標值減去運動的值再除以十,就不可能會得到目標值,所以我們會陷入一個無限循環的步驟中,那么我們就對leader進行四舍五入操作,當他接近目標值時就直接對其四舍五入等于目標值,那么運動到此為止就可以結束了。大家可以自己嘗試一下喲。
4. Math對象###
4.1 Math.round(); //對小數進行四舍五入操作
4.2 Math.random()*10; //隨機產生一個0到10之間的浮點數,不包括10
5. 小米廣告/窗簾效果
又是一個練手的demo,就不那么多廢話了。直接看一下縮寫版的操作步驟吧。
布局
鼠標放入box后img的位置的計算
鼠標移出后停止位置的改變
出現詭異情況時,請清空計時器
改變位置時的步長
CSS代碼:
*{
margin: 0;
padding: 0;
}
div{
width: 512px;
height: 400px;
border: 1px solid #000;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 100px auto;
overflow: hidden;
position: relative;
}
div span{
position: absolute;
left:0;
width:100%;
height:200px;
cursor: pointer;
}
div span:nth-of-type(1){
top:0;
/*background: red;*/
}
div span:nth-of-type(2){
top:200px;
/*background: blue;*/
}
div img{
position: absolute;
top:0;
left:0;
}
HTML代碼:
<div>

<span></span>
<span></span>
</div>
JS代碼:
var img = document.getElementsByTagName("img")[0];
var box = document.getElementsByTagName("div")[0];
var spanTop = document.getElementsByTagName("span")[0];
var spanBottom = document.getElementsByTagName("span")[1];
var timer = null;
var leader = 0;
// console.log( leader > -parseInt(img.offsetHeight - box.offsetHeight));
//鼠標位于廣告圖上半部分時
spanTop.onmouseover= function () {
clearInterval(timer);
timer = setInterval(function () {
// console.log(leader);
if(leader > -parseInt(img.offsetHeight - box.offsetHeight)){
leader-=1;
}
else{
leader = -(parseInt(img.offsetHeight - box.offsetHeight));
clearInterval(timer);
}
img.style.top=leader+"px";
},3);
};
spanTop.onmouseout= function () {
clearInterval(timer);
};
//鼠標位于廣告圖下半部分時
spanBottom.onmouseover = function () {
clearInterval(timer);
timer = setInterval(function () {
if(leader<0)leader+=1;
else {
leader=0;
clearInterval(timer);
}
img.style.top=leader+"px";
},3)
};
spanBottom.onmouseout = function () {
clearInterval(timer);
};
orz,時隔兩天再看自己的代碼,慘不忍睹,冗余太多。書寫的也很差勁,后面會多寫代碼提升自己代碼的可閱讀性。
6. 倒計時跳轉頁面###
頁面提示:將在幾秒后跳轉到某個頁面,幾是一直變化的值
利用到window對象的location屬性
window.location.href = "http://www.baidu.com/"
<button>點擊開始計時</button>
<p>頁面將在5s后跳轉至百度</p>
<script>
var btn = document.getElementsByTagName("button")[0];
var p = document.getElementsByTagName("p")[0];
var str = p.innerText;
var second = 0;
for(var i=0;i<str.length;i++){
if(parseInt(str.charAt(i),10))
second = parseInt(str.charAt(i));
}
方案一:settimeout實現,遞歸函數
function loadBd(){
second--;
console.log(second);
if(!second){
window.location.;
}
else
{
p.innerText = "頁面將在"+second+"s后跳轉至百度";
setTimeout(loadBd,1000);
}
}
btn.onclick=loadBd;
方案二:setInterval實現
/*
var timer = null;
btn.onclick= function () {
clearInterval(timer);
timer = setInterval(function () {
// --second;
p.innerText = "頁面將在"+--second+"s后跳轉至百度";
if(!second)window.location.;
},1000);
}
*/
7.簡單的輪播###
從右向左滾動,注意圖片的銜接
布局需要注意,用前面的圖片去銜接到最后一張圖片以后,避免跳轉時的尷尬。
<ul>

<li>

</li>

<li>

<li>

<li>

</li>
</ul>
滾動超出顯示框長度時重置ul位置
CSS代碼
*{
margin: 0;
padding: 0;
}
div{
border: 1px solid #000;
width: 600px;
height: 200px;
margin: 0 auto;
position: relative;
overflow: hidden;
top: 100px;
}
div ul{
width: 400%;
position: absolute;
top: 0;
left: 0;
}
div ul li{
list-style:none;
float: left;
cursor: pointer;
user-select: none;
}
HTML代碼:
<div>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
JS代碼:
var ul = document.getElementsByTagName("ul")[0];
var timer = null, leader = 0;
function lb(){
clearInterval(timer);
timer = setInterval(function () {
leader=leader==-1190?leader=0:leader-=5;
ul.style.left = leader+"px";
},30);
}
lb();
document.getElementsByTagName("div")[0].onmouseover = function () {
clearInterval(timer);
};
document.getElementsByTagName("div")[0].onmouseout = function () {
lb();
};
8.淘寶廣告圖的輪播###
注意排他思想的時候,以及定義一個變量用作索引保存當前所展示圖片的位置
CSS代碼:
*{
margin: 0;
padding: 0;
}
.box{
width: 300px;
height: 250px;
margin: 100px auto;
border: 1px solid #000;
cursor: pointer;
}
.box li{
list-style-type: none;
line-height:27px;
border-bottom: 1px solid #000;
text-align: center;
}
.box li:nth-child(9),
.box li:nth-child(18){
border-bottom:none;
}
.box ul:nth-of-type(1){
float: left;
width: 50px;
}
.box ul:nth-of-type(2){
float: right;
}
.box img{
border-right: 1px solid #000;
border-left: 1px solid #000;
margin: 0 auto;
}
.current{
background: url("images/taobao/bg.gif") repeat-x;
}
HTML代碼:
<div class="box">
<ul>
<li class="current">冬裙</li>
<li>呢大衣</li>
<li>圍巾</li>
<li>女包</li>
<li>女褲</li>
<li>女靴</li>
<li>棉服</li>
<li>毛衣</li>
<li>牛仔褲</li>
</ul>

<ul>
<li>男包</li>
<li>男棉服</li>
<li>男毛衣</li>
<li>男靴</li>
<li>登山鞋</li>
<li>皮帶</li>
<li>皮衣</li>
<li>羽絨服</li>
<li>雪地靴</li>
</ul>
</div>
JS代碼:
var lis = document.getElementsByTagName("li");
var img = document.getElementsByTagName("img")[0];
var box = document.getElementsByClassName("box")[0];
var imgSrcArr = ["images/taobao/冬裙.jpg","images/taobao/呢大衣.jpg","images/taobao/圍巾.jpg","images/taobao/女包.jpg","images/taobao/女褲.jpg","images/taobao/女靴.jpg","images/taobao/棉服.jpg","images/taobao/毛衣.jpg","images/taobao/牛仔褲.jpg","images/taobao/男包.jpg","images/taobao/男棉服.jpg","images/taobao/男毛衣.jpg","images/taobao/男靴.jpg","images/taobao/登山鞋.jpg","images/taobao/皮帶.jpg","images/taobao/皮衣.jpg","images/taobao/羽絨服.jpg","images/taobao/雪地靴.jpg"];;
var loop=0;
var timer = null;
function tb() {
timer = setInterval(function () {
loop++;
if (loop==18)loop=0;
for(let i = 0; i < lis.length; i++){
lis[i].className = "";
}
img.src = imgSrcArr[loop];
lis[loop].className = "current";
},1000);
};
tb();
box.onmouseover= function () {
clearInterval(timer);
};
box.onmouseout= function () {
tb();
}
9.左右向輪播
節流思想
原理:當進入輪播事件時,判斷flag的值,如果真,則直接跳出函數,如果假,那么設置為真并執行函數內容,當函數所展現結果達到預期值,則改變flag值使其可以再次進入函數
方法一:圖片總數+1個li的輪播
CSS代碼:
*{
margin: 0;
padding: 0;
}
#box{
border: 1px solid #000;
width: 640px;
height: 270px;
position: relative;
margin:100px auto;
overflow: hidden;
}
#box ul{
width: 800%;
position: absolute;
left:0;
top: 0;
}
#box ul li{
float: left;
list-style:none;
}
#box span{
font-size:60px;
color: white;
background: rgba(0,0,0,.5);
position: absolute;
cursor: pointer;
}
#box span:nth-of-type(1){
top:105px;
left:0;
}
#box span:nth-of-type(2){
top:105px;
right:0;
}
HTML代碼:
<div id="box">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<span><</span>
<span>></span>
</div>
JS代碼:
//獲取所需要用到的元素
var ul = document.getElementsByTagName("ul")[0];
var span = document.getElementsByTagName("span");
var left = span[0],right = span[1];
//節流思想
var flag = false;
//設置輪播圖所需要用到的變量
var timer = null, loop = 0, step = 640, sign = 0; //loop為當前box中即將要顯示圖片的索引值,step為每張圖的寬度,sign為改變ul位置的中間值
//右邊span點擊時響應事件
right.onclick = function () {
if(flag)return; //節流思想的調用,防止多次點擊輪播圖會多次滾動,每次輪播都需要在當前輪播完成以后才可以開始。原理:當進入輪播事件時,判斷flag的值,如果真,則直接跳出函數,如果假,那么設置為真并執行函數內容,當函數所展現結果達到預期值,則改變flag值使其可以再次進入函數
flag =true;
clearInterval(timer); //每次執行代碼前先清空一遍計時器,否則會出現計時器多次啟動的奇怪現象
loop++; //每次點擊以后loop索引自動加1,對應當前所顯示圖片索引位置
if(loop>5){ //當索引達到圖片張數最大時,loop則改變為1,意為接下來要顯示第二張圖,并且sign變為0,從第一張圖過度到第二張圖
loop = 1;
sign = 0;
}
timer = setInterval(function () {
sign -= 1; //ul向左滾動,每30毫秒移動1個像素
if(sign < -loop * step){ //當sign值小于loop個圖片寬度時候,sign則等于loop個圖片寬度的絕對值
sign = -loop * step;
flag = false;
clearInterval(timer);
}
ul.style.left = sign +"px"; //改變ul的位置為sign的值
},2); //每2毫秒改變一次輪播圖位置
};
//左邊span點擊時響應事件
left.onclick = function () { //執行體邏輯同右邊span點擊相似,不贅述
if(flag)return;
flag = true;
clearInterval(timer);
loop--; //當前索引向前滾
if (loop<0){ //當前顯示圖片位置如果比第一張小,則讓他變成第五張圖片,并且sign變為過度圖片所在位置,之后由于定時器的原因會繼續向第五張圖片方向滾動
loop = 4;
sign = -(loop+1) * step;
}
timer = setInterval(function () {
sign += 1; //圖片從左向右移動,sign的值是遞增的過程,當他大于當前即將顯示圖片位置時,則sign的值更改為當前所顯示圖片的位置
if(sign>-loop*step){
sign = -loop*step;
clearInterval(timer);
flag = false;
}
ul.style.left = sign + "px";
},2)
}
方法二:兩個li的輪播方式
CSS代碼:
*{
margin: 0;
padding: 0;
user-select: none;
}
#box{
border: 1px solid #000;
margin: 100px auto;
width: 640px;
height: 270px;
position: relative;
overflow: hidden;
}
#box ul{
width: 220%;
position: absolute;
top: 0;
left: 0;
}
#box ul li{
float: left;
list-style:none;
}
#box span{
position: absolute;
font-size:60px;
background: rgba(0,0,0,.5);
color: #fff;
cursor: pointer;
}
#box span:nth-of-type(1){
top: 105px;
left: 0;
}
#box span:nth-of-type(2){
top: 105px;
right: 0;
}
HTML代碼:
<div id="box">
<ul>
<li></li>
<li></li>
</ul>
<span><</span>
<span>></span>
</div>
JS代碼:
//獲取所需要的標簽
var span = document.getElementsByTagName("span");
var left = span[0], right = span[1];
var ul = document.getElementsByTagName("ul")[0];
var img = document.getElementsByTagName("img");
var img1 = img[0], img2 = img[1];
//準備輪播圖切換時所需要的數據
var imgSrcArr = [
"images/zuoyouLunBo/01.jpg",
"images/zuoyouLunBo/02.jpg",
"images/zuoyouLunBo/03.jpg",
"images/zuoyouLunBo/04.jpg",
"images/zuoyouLunBo/05.jpg",
"images/zuoyouLunBo/01.jpg",
];
//準備輪播圖所需要的變量
var timer = null, loop = 0, leader = 0; //loop表示即將要顯示的圖片在數組重的索引,leader為改變ul位置的中間值
//節流思想
var flag = false;
//右邊按鈕點擊時所響應事件
right.onclick= function () {
if(flag)return; //節流思想的使用
flag = true;
clearInterval(timer); //每次點擊都先清空一遍計時器,以保證多次點擊不會開啟多個計時器
loop++; //每次點擊以后要顯示圖片的索引
if(loop ==5)loop = 0; //當圖片到達最后一張時,那么即將顯示的圖片則為第一張
timer = setInterval(function () { //設置一個定時器,用來改變ul所在的位置與對應的li中所顯示的圖片
leader-=15; //圖片向左移動,則ul的left位置會越來越小
if(leader < -640){ //當向左移動的位置剛好達到一張圖片的距離時,停止運動,并將ul放回原位,同時修改兩個img標簽所對應的路徑為正確的圖片
clearInterval(timer);
img1.src = imgSrcArr[loop];
img2.src = imgSrcArr[loop+1];
leader = 0;
flag = false;
}
ul.style.left = leader + "px";
},30);
};
//左邊按鈕點擊時所響應事件
left.onclick = function () {
if(flag)return; //節流思想的使用
flag = true;
clearInterval(timer);
loop--; //每次點擊后要顯示的圖片的索引值自行更改,點擊左邊那么ul向右滾動
if(loop<0)loop=4; //當點擊完第一張后,即將顯示的應為最后一張
leader = -640; //每次點擊左邊時都將ul向左放置一張輪播圖的寬度,如果非固定圖片,那么此時該值被稱為魔鬼數字,應用變量替換掉。
timer = setInterval(function () { //設置一個計時器,ul的left值在-640的基礎上每30毫秒向右滾動30個像素,當ul的left值大于一個圖片寬時,將ul的left值設為零并清空計時器
leader+=30;
img1.src = imgSrcArr[loop]; //修改兩張圖片的src屬性,以改變顯示的圖片內容 此處有個小bug,將更改圖片路徑的兩條語句寫在setInterval外部會導致輪播圖出現閃爍的情況,內部則根據預期目標實現效果
img2.src = imgSrcArr[loop+1];
if(leader>0){
clearInterval(timer);
flag = false;
leader = 0;
}
ul.style.left = leader + "px";
},30);
}