一、jquery常用篩選方法
以下為jquery的常用篩選方法:
代碼示例如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>篩選方法</title> <style type="text/css"> li.active { font-size: 50px; } </style> </head> <body> <ul> <li class="danger">1</li> <li><a href="#">luffy</a></li> <li class="danger">3</li> <li>4</li> <a href="#"> 百度</a> <a href="#" id="anchor">百度</a> </ul> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function () { console.log($('li')); // 輸出:jQuery.fn.init(4) 類似數組的索引 // jQuery的遍歷方法:.each() // $('li').each(function (index,ele) { // 索引,對象 $('ul').children().each(function (index, ele) { console.log(ele); // <li class="danger">1</li> : js的dom對象 console.log(index); // 0 : index // 判斷當前匹配元素里是否有這個類名 var isDanger = $(this).hasClass('danger'); if (isDanger) { $(this).css('color','red'); } else { $(this).css('font-size','20px'); } }) // children() console.log($('ul').children()); console.log($('li')); // 同上 console.log($('ul').children('.danger')); // parent() console.log($('li').parent()); // jQuery.fn.init [ul, prevObject:... // last() 最后一個元素 prev:前一個元素 console.log($('li').last().prev()); // jQuery.fn.init [li.danger console.log($('li').last().prevAll()); // silbings:篩選給定的同胞同類元素(不包括給定元素本身) console.log($('li').siblings('li')); console.log($('#anchor').siblings('a')); // jQuery.fn.init [a, prevObject.. // 鼠標指向的li標簽變大,移走后變小的選項卡效果 $('li').hover(function () { $(this).addClass('active').siblings('li').removeClass('active'); }) }) </script> </html>
二、應用篩選方法實現選項卡
選項卡這種效果在網頁中應用非常多,效果如下圖所示:
示例代碼如下所示:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{padding: 0;margin: 0;} ul{ list-style: none; } /*清除浮動產生的問題 浮動產生的原因:父級元素沒有填充高度以及填充的時候父級撐不開,導致子級元素浮動*/ #box:after{ /*偽類選擇器*/ content: ""; display: block; clear: both; /* 盒子左右兩邊都不浮動 */ } #box{width: 800px;border: 1px solid black;margin: 20px auto;background: blue;} #leftBox{width: 200px;float: left;} #leftBox li{width: 200px;height: 89px;background: red;margin-bottom: 2px;color: white;font: 50px/89px "黑體"; text-align: center;} #rightBox div{display: none;float: left; width: 600px;} #rightBox p{width:100%;height: 325px;font: 100px/325px "黑體";text-align: center;background: greenyellow } /* font:100px/325px; 代表font-size:100px;line-height:325px; 垂直居中*/ /*text-align:center; 代表中心對齊*/ /*父元素設置display:table使它成為一個塊級表格元素 * 子元素設置display:table-cell使子元素成為表格單元格,就好比是在表格中一樣*/ #rightBox ul{width: 600px;display: table;} #rightBox li{display: table-cell;background: purple;height: 40px;border-right: 2px solid blue;font: 30px/40px "黑體";text-align: center;color: white;} #leftBox .active{background: yellow;color: black;} #rightBox .active{background: white;color: black;} </style> </head> <body> <div id="box"> <ul id="leftBox"> <li>a</li> <li>b</li> <li>c</li> <li>d</li> </ul> <div id="rightBox"> <div style="display: block"> <p>a1</p> <ul> <li class="active">a1</li> <li>a2</li> <li>a3</li> <li>a4</li> </ul> </div> <div> <p>b1</p> <ul> <li class="active">b1</li> <li>b2</li> <li>b3</li> <li>b4</li> </ul> </div> <div> <p>c1</p> <ul> <li class="active">c1</li> <li>c2</li> <li>c3</li> <li>c4</li> <li>c5</li> <li>c6</li> </ul> </div> <div> <p>d1</p> <ul> <li class="active">d1</li> <li>d2</li> <li>d3</li> <li>d4</li> </ul> </div> </div> </div> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ //鼠標移入的時候 $('#leftBox li').mouseover(function(){ //修改自己的樣式 siblings:選到本身以外其他兄弟元素,去除active類對應的樣式 $(this).addClass('active').siblings('li').removeClass('active'); //修改右邊的div console.log($(this).index()); // 利用$(this).index()取當前對象的索引,輸出:0\1\2\3 // eq(index):獲取第N個元素的篩選方法 show\hide方法控制元素顯示隱藏 $('#rightBox div').eq($(this).index()).show().siblings('div').hide(); }) $('#rightBox li').click(function(){ $(this).addClass('active').siblings('li').removeClass('active'); var liValue = $(this).html(); // 得到對應<li>標簽的值 // 找到li元素的父元素的前一個元素————<p> 給<p>設置html值 $(this).parent().prev().html(liValue); }) }) </script> </html>
1、使用:after偽元素解決經典清除浮動的問題
浮動產生的原因:父級元素沒有填充高度以及填充的時候父級撐不開,導致子級元素浮動
#box:after{ /*偽類選擇器*/ content: ""; display: block; clear: both; /* 盒子左右兩邊都不浮動 */ }
2、注意font:100px/325px; 這種特殊寫法
#rightBox p{width:100%;height: 325px;font: 100px/325px "黑體";text-align: center;background: greenyellow } /* font:100px/325px;代表 font-size:100px; line-height:325px; 垂直居中*/ /*text-align:center; 代表中心對齊*/
3、display: table; 和 display: table-cell;
/*父元素設置display:table使它成為一個塊級表格元素 * 子元素設置display:table-cell使子元素成為表格單元格,就好比是在表格中一樣*/ #rightBox ul{width: 600px;display: table;} #rightBox li{display: table-cell;background: purple;height: 40px;border-right: 2px solid blue;font: 30px/40px "黑體";text-align: center;color: white;}
4、$(this).index()可以得到當前對象的索引。兩邊的元素可以通過索引和eq()方法進行聯動:
// eq(index):獲取第N個元素的篩選方法 show\hide方法控制元素顯示隱藏 $('#rightBox div').eq($(this).index()).show().siblings('div').hide();
5、選項卡實現原理:監聽鼠標移入事件,觸發事件后選到當前被移入的元素,用addClass添加類以此來添加樣式,再用siblings選到其他兄弟元素,去除類以此來去除樣式。
$(function(){ //鼠標移入的時候 $('#leftBox li').mouseover(function(){ //修改自己的樣式 siblings:選到本身以外其他兄弟元素,去除active類對應的樣式 $(this).addClass('active').siblings('li').removeClass('active'); //修改右邊的div console.log($(this).index()); // 利用$(this).index()取當前對象的索引,輸出:0\1\2\3 // eq(index):獲取第N個元素的篩選方法 show\hide方法控制元素顯示隱藏 $('#rightBox div').eq($(this).index()).show().siblings('div').hide(); }) $('#rightBox li').click(function(){ $(this).addClass('active').siblings('li').removeClass('active'); var liValue = $(this).html(); // 得到對應<li>標簽的值 // 找到li元素的父元素的前一個元素————<p> 給<p>設置html值 $(this).parent().prev().html(liValue); }) })
6、類似的點擊右下方按鈕,切換顯示內容。是通過parent()方法找到當前元素的父級元素ul,再通過prev()方法定位到元素p,再通過html()方法賦值,修改顯示內容。
var liValue = $(this).html(); // 得到對應<li>標簽的值 // 找到li元素的父元素的前一個元素————<p> 給<p>設置html值 $(this).parent().prev().html(liValue);
三、小米官網案例——鼠標移動彈出對應文檔介紹
小米網介紹彈出效果如下所示:
彈出效果代碼示例如下:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> /* 清除默認樣式 */ *{ padding: 0; margin: 0; } ul{list-style: none;} .wrap{width: 980px;height: 612px;margin: 20px auto 0px;background: #f4f3f4;border: 1px solid gray;} ul li{float: left;margin-left: 10px;position: relative;overflow: hidden;/*超出部分隱藏*/width: 233px;height: 300px;} ul li p{ width: 233px; height: 100px; background: rgba(245,102,51,.7); position: absolute; bottom: -100px; /*將p標簽里的內容蓋住了*/ text-align: center; color: white; line-height: 100px; } </style> </head> <body> <div class="wrap"> <ul> <li><a href="#"><img src="images/xiaomi_01.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_02.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_03.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_04.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_05.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_07.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_08.png"/></a><p>百度一下,你就知道</p></li> <li><a href="#"><img src="images/xiaomi_09.png"/></a><p>百度一下,你就知道</p></span></li> </ul> </div> </body> <script src="./jquery-3.3.1.js"></script> <script type="text/javascript"> //mouseenter進入調用,mouseleave離開調用————這兩個方法實現hover $('.wrap li').hover(function(){ // 第一個回調函數是mouseenter方法的實現 // stop():在鼠標移入移出的時,在激活動畫前,先停止動畫,解決快速移動鼠標時,鋼琴效果 $(this).children('p').stop(true).animate({bottom:0},100); },function(){ // 第二個回調函數是mouseleave方法的實現 $(this).children('p').stop(true).animate({bottom:-100},100); // 將p標簽內容再次蓋住 }) </script> </html>
1、<div>下有<ul>,<ul>下有<li>,每個<li>中包含一個<a><img/></a>和一個<p>。因此給li設置相對定位,且overflow:hidden;來隱藏超出部分。同時給<p>設置絕對定位,並設置bottom:-100px;超出<li>范圍,達到將p標簽的內容蓋住的效果。
2、hover() 方法規定當鼠標指針懸停在被選元素上時要運行的兩個函數。hover方法觸發 mouseenter 和 mouseleave 事件。
// 語法 $(selector).hover(inFunction,outFunction) //mouseenter進入調用,mouseleave離開調用————這兩個方法實現hover $('.wrap li').hover(function(){ // 第一個回調函數是mouseenter方法的實現 $(this).children('p').animate({bottom:0},100); },function(){ // 第二個回調函數是mouseleave方法的實現 $(this).children('p').animate({bottom:-100},100); // 將p標簽內容再次蓋住 })
3、上述代碼雖然實現了<p>標簽彈出的效果,但是快速移動鼠標時,會發現多個標簽都處於彈出收回狀態,產生波浪效果。
因此使用stop()方法:在鼠標移入移出時,先停止動畫。
$('.wrap li').hover(function(){ // 第一個回調函數是mouseenter方法的實現 // stop():在鼠標移入移出的時,在激活動畫前,先停止動畫,解決快速移動鼠標時,鋼琴效果 $(this).children('p').stop(true).animate({bottom:0},100); },function(){ // 第二個回調函數是mouseleave方法的實現 $(this).children('p').stop(true).animate({bottom:-100},100); // 將p標簽內容再次蓋住 })
四、焦點輪播圖
要實現的焦點輪播圖效果如下所示:
代碼示例如下所示:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> /*清除默認樣式*/ *{padding: 0;margin: 0;} ul,ol{list-style: none;} #wrap{width: 650px;height: 250px;margin: 100px auto 0;background: red;overflow: hidden;position: relative;} /*#wrap img{display: block;}*/ #wrap ul{height: 250px;position: relative;z-index: 1;} #wrap ol{height: 30px;position: absolute;z-index: 2;bottom: 0;right: 0;} /*通過z-index調整層級關系,顯現出1、2、3、4按鈕*/ #wrap>ul>li{ /* 子代選擇器,配置的<li>樣式區分ul下或ol下 */ position: absolute; top:0; left: 0; } #wrap>ol>li{ float: left; width: 20px; height: 20px; text-align: center; line-height: 20px; border: 1px solid white; background: gray; margin-right: 5px; } #wrap>ol>li:hover{ /*設置鼠標形狀*/ cursor: pointer; } #wrap li.active{ /* 切換到對應li顯示效果不同(鼠標移動上去,抬起效果) */ padding: 2px; color: orange; margin-top: -4px; border: 1px solid orange; } </style> </head> <body> <div id="wrap"> <ul> <!--設置絕對定位之后 脫離標准流 最后一個盒子層級提升了, 為了默認顯示第一張圖而不是最后一張圖,給第一個li設置z-index --> <li style="z-index: 1;"><a href="#"><img src="./images/01.jpg"/></a></li> <li><a href="#"><img src="./images/02.jpg"/></a></li> <li><a href="#"><img src="./images/03.jpg"/></a></li> <li><a href="#"><img src="./images/04.jpg"/></a></li> <li><a href="#"><img src="./images/05.jpg"/></a></li> </ul> <ol> <li class="active">1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ol> </div> </body> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript"> $(function(){ //控制層級關系的索引 var index = 0; $('#wrap>ol>li').mouseenter(function(){ index++; // 鼠標移進去時,不管是移動哪一個,都會自增 //修改下標 //當前li對象》添加active類來修改樣式》取到每個li同胞》刪除active類,取消同胞的樣式 $(this).addClass('active').siblings('li').removeClass('active'); //修改圖片 //選取到ul下的所有li對象》eq取到當前下標對應的索引》修改樣式,設置z-index覆蓋其他li 》animate完成動畫效果1秒內移動覆蓋 $('#wrap>ul>li').eq($(this).index()).css({left:650,'z-index':index}).animate({ left: 0 // 這里不設置left:0的話,li都位於left:650(圖片展示的位置確實是left:0) },1000) }) }) </script> </html>
分析輪播圖實現:
1、輪播圖是由同級的ul和ol組成他們的父級div。div設置了相對定位和overflow:hidden;因此超出div的部分會被隱藏。
#wrap{width: 650px;height: 250px;margin: 100px auto 0;background: red;overflow: hidden;position: relative;}
2、z-index的設置是實現輪播圖的關鍵要素,其中ul>li設置絕對定位之后 脫離標准流 最后一個盒子層級提升了,為了默認顯示第一張圖而不是最后一張圖,給第一個li設置z-index
<li style="z-index: 1;"><a href="#"><img src="./images/01.jpg"/></a></li> <li><a href="#"><img src="./images/02.jpg"/></a></li> <li><a href="#"><img src="./images/03.jpg"/></a></li> <li><a href="#"><img src="./images/04.jpg"/></a></li>
3、通過鼠標移入ol>li標簽來切換輪播圖,這需要mouseenter方法實現。同時被鼠標指向的li標簽樣式將發生改變。
//修改下標 //當前li對象》添加active類來修改樣式》取到每個li同胞》刪除active類,取消同胞的樣式 $(this).addClass('active').siblings('li').removeClass('active');
4、鼠標指向ol的li標簽,li標簽的樣式更改,但是同時還需要修改到對應的圖片。需要用eq($(this).index())來取到對應的索引值。
//修改圖片 //選取到ul下的所有li對象》eq取到當前下標對應的索引》修改樣式,設置z-index覆蓋其他li 》animate完成動畫效果1秒內移動覆蓋 $('#wrap>ul>li').eq($(this).index()).css({left:650,'z-index':index}).animate({ left: 0 // 這里不設置left:0的話,li都位於left:650(圖片展示的位置確實是left:0) },1000)
5、需要設置一個控制層級關系的索引:var index= 0;每次鼠標移入都自增一次,保證從頭到尾指向一遍后,再指向前面的li標簽,均能夠保證z-index的值最大能夠正常覆蓋。注意$(this).index()和index變量的區別。
//控制層級關系的索引 var index = 0; $('#wrap>ol>li').mouseenter(function(){ index++; // 鼠標移進去時,不管是移動哪一個,都會自增 //修改下標 //當前li對象》添加active類來修改樣式》取到每個li同胞》刪除active類,取消同胞的樣式 $(this).addClass('active').siblings('li').removeClass('active'); //修改圖片 //選取到ul下的所有li對象》eq取到當前下標對應的索引》修改樣式,設置z-index覆蓋其他li 》animate完成動畫效果1秒內移動覆蓋 $('#wrap>ul>li').eq($(this).index()).css({left:650,'z-index':index}).animate({ left: 0 // 這里不設置left:0的話,li都位於left:650(圖片展示的位置確實是left:0) },1000) console.log($(this).index()); console.log(index); })
五、動態實現輪播圖
前面焦點輪播圖實現了點選的方式實現圖片輪播,這種顯示效果過於呆板,還需要添加動態輪播功能。顯示效果如下所示:
點擊輪播按鈕,圖片開始自動輪播,點擊暫停按鈕,圖片輪播停止,顯示停止在當前圖片。代碼示例如下所示:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{padding: 0;margin: 0;} ul{list-style: none;} #box{ /*圖片的寬高 240px 180px*/ width: 240px; height: 180px; position: relative; margin: 50px auto; /*overflow 屬性規定當內容溢出元素框時發生的事情 hidden:內容會被修剪,並且其余內容是不可見的*/ overflow: hidden; } ul{ width: 960px; /* 240*4=960 */ position: absolute; } ul li{ /*左浮動之后,所有圖片都在一排展示*/ float: left; } p { position: absolute; left: 80px; bottom: 30px; } p span { color: red; display: inline-block; width: 20px; height: 20px; line-height: 20px; text-align: center; /*cursor 屬性規定要顯示的光標的類型(形狀) pointer:光標呈現為指示鏈接的指針(一只手)*/ cursor: pointer; } p span.active { color: white; background: green; /*背景顏色*/ } </style> </head> <body> <div id="box"> <ul> <!--顯示輪播的圖片--> </ul> <p> <!--顯示索引--> </p> </div> <button id="play">輪播吧!</button> <button id="stop">暫停!</button> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ //1.獲取本地的圖片數據 以后再后面的課程中這些數據會從后端服務器獲取 var imgArr = ['./01.jpg','./02.jpg','./03.jpg','./04.jpg']; //2.動態的生成圖片 for(var i = 0; i < imgArr.length;i++){ // 字符串拼接實現動態添加標簽 $('ul').append("<li><img src="+imgArr[i]+"></li>") } //3.生產索引 var str = ''; // each(function(index,element))為每個匹配的元素規定運行的函數 $('li').each(function (i,ele) { str += "<span>"+(i+1)+"</span>"; }) console.log(str); // <span>1</span><span>2</span><span>3</span><span>4</span> $('p').html(str); // 4.默認設置索引的一個active $('span:first').addClass('active'); var index = 0; // index定義為全局變量 // 5.點擊索引 $('span').click(function () { $(this).addClass('active').siblings('span').removeClass('active'); // 點選到的按鈕修改樣式 // 獲取我當前點擊的索引 index = $(this).index(); // 設為全局變量 //方法1: // $('ul').css('left',-240*index); // 所有圖片都在一排,依次排列 //方法2: $('ul').animate({ left: -240*index },100) }) // 6.自動輪播 var timer = null; $('#play').click(function () { // 開啟定時器: 1.索引跟着走;2.圖片跟着走。 timer = setInterval(next,1000); function next() { // console.log(index++); if(index == $('li').length-1) { // 圖片結尾了。第四張了 index = 0; // 修改span標簽的第一個active $('p span').eq(index).addClass('active').siblings('span').removeClass('active'); // 修改ul的樣式 $('ul').css('left',0); } else { index++; // 修改后三個span標簽的active $('p span').eq(index).addClass('active').siblings('span').removeClass('active'); // 修改ul的樣式 $('ul').css('left',-240*index); } } }) // 7.暫停輪播 $('#stop').click(function () { clearInterval(timer); }) }) </script> </html>
動態輪播圖實現要點:
1、在html代碼中並沒有在ul下添加li標簽,而是通過字符串拼接動態添加標簽。把拼接時需要的圖片存放在數組中。ul>li標簽css樣式都設置了左浮動,因此所有圖片在一排展示。overflow 屬性規定當內容溢出元素框時發生的事情;hidden:內容會被修剪,並且其余內容是不可見的。
//1.獲取本地的圖片數據 以后再后面的課程中這些數據會從后端服務器獲取 var imgArr = ['./01.jpg','./02.jpg','./03.jpg','./04.jpg']; //2.動態的生成圖片 for(var i = 0; i < imgArr.length;i++){ // 字符串拼接實現動態添加標簽 $('ul').append("<li><img src="+imgArr[i]+"></li>") }
2、html代碼中p標簽內也是空的,也是利用字符串拼接動態添加span標簽,添加圖片索引序號。
//3.生產索引 var str = ''; // each(function(index,element))為每個匹配的元素規定運行的函數 $('li').each(function (i,ele) { str += "<span>"+(i+1)+"</span>"; }) console.log(str); // <span>1</span><span>2</span><span>3</span><span>4</span> $('p').html(str);
3、同經典輪播圖類似,給p>span標簽里的這些圖片索引,設置active樣式,默認給第一個標簽添加active類。
// 4.默認設置索引的一個active $('span:first').addClass('active'); p span.active { color: white; background: green; /*背景顏色*/ }
4、使用click()方法來設置點選到<span>標簽切換輪播圖,由於所有圖片都是在一行排列,因此通過 left: -240*index; 這種方法把圖片偏移到div顯示范圍內展示。
// 5.點擊索引 $('span').click(function () { $(this).addClass('active').siblings('span').removeClass('active'); // 點選到的按鈕修改樣式 // 獲取我當前點擊的索引 index = $(this).index(); //方法1: // $('ul').css('left',-240*index); // 所有圖片都在一排,依次排列 //方法2: $('ul').animate({ left: -240*index },100) })
5、點擊按鈕開始輪播,啟動定時器setInterval()方法可以按照指定的周期(毫秒計)來調用函數或計算表達式。
在函數next中,在index的值等於圖片索引長度-1時,說明圖片結尾了,輪播到第四張圖片了,需要設定第一個span標簽為active,ul的樣式修正為第一張圖顯示:$('ul').css('left',0);其他情況下,則是為當前index的span添加為active類,給它的其他兄弟刪除active,$('ul').css('left',-240*index);修改ul樣式,展現當前圖片。
// 6.自動輪播 var timer = null; $('#play').click(function () { // 開啟定時器: 1.索引跟着走;2.圖片跟着走。 timer = setInterval(next,1000); function next() { // console.log(index++); if(index == $('li').length-1) { // 圖片結尾了。第四張了 index = 0; // 修改span標簽的第一個active $('p span').eq(index).addClass('active').siblings('span').removeClass('active'); // 修改ul的樣式 $('ul').css('left',0); } else { index++; // 修改后三個span標簽的active $('p span').eq(index).addClass('active').siblings('span').removeClass('active'); // 修改ul的樣式 $('ul').css('left',-240*index); } }
})
6、setInterval() 方法會不停地調用函數,直到 clearInterval() 被調用或窗口被關閉。因此停止輪播使用clearInterval方法。
// 7.暫停輪播 $('#stop').click(function () { clearInterval(timer); })
六、jQuery的事件
1、事件的概念
HTML中與javascript交互是通過事件驅動來實現的,例如鼠標點擊事件、頁面的滾動事件onscroll等等,可以向文檔或者文檔中的元素添加事件偵聽器來預訂事件。想要知道這些事件是在什么時候進行調用的,就需要了解一下“事件流”的概念。
2、事件流
事件流描述的是從頁面中接收事件的順序。
“DOM2級事件”規定的事件流包括三個階段:(1)事件捕獲階段;(2)處於目標階段;(3)事件冒泡階段。
事件流演示代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件流</title> <script> window.onload = function(){ // 取到DOM元素 js的DOM對象 var oBtn = document.getElementById('btn'); // addEventListener添加事件偵聽器 // 第一個參數:click事件的名字 第二個參數:回調函數 觸發事件發生的事情 // 第三個參數:true/false true,表示在捕獲階段調用事件處理程序;如果是false,表示在冒泡階段調用事件處理程序 oBtn.addEventListener('click',function(){ console.log('btn處於事件捕獲階段'); }, true); oBtn.addEventListener('click',function(){ console.log('btn處於事件冒泡階段'); }, false); // 為文檔增加事件 document.addEventListener('click',function(){ console.log('document處於事件捕獲階段'); }, true); document.addEventListener('click',function(){ console.log('document處於事件冒泡階段'); }, false); // 為文檔元素增加事件 document.documentElement.addEventListener('click',function(){ console.log('html處於事件捕獲階段'); }, true); document.documentElement.addEventListener('click',function(){ console.log('html處於事件冒泡階段'); }, false); // 為body增加事件 document.body.addEventListener('click',function(){ console.log('body處於事件捕獲階段'); }, true); document.body.addEventListener('click',function(){ console.log('body處於事件冒泡階段'); }, false); }; </script> </head> <body> <a href="javascript:;" id="btn">按鈕</a> </body> </html>
在瀏覽器上執行代碼,控制台輸出如下:
document處於事件捕獲階段 html處於事件捕獲階段 html處於事件冒泡階段 document處於事件冒泡階段 <!--點擊按鈕后--> document處於事件捕獲階段 html處於事件捕獲階段 body處於事件捕獲階段 btn處於事件捕獲階段 btn處於事件冒泡階段 body處於事件冒泡階段 html處於事件冒泡階段 document處於事件冒泡階段
3、addEventListener
addEventListener 是DOM2 級事件新增的指定事件處理程序的操作,這個方法接收3個參數:要處理的事件名、作為事件處理程序的函數和一個布爾值。最后這個布爾值參數如果是true,表示在捕獲階段調用事件處理程序;如果是false,表示在冒泡階段調用事件處理程序。
4、document、documentElement、document.body三者間的關系
document代表的是整個html頁面;
document.documentElement代表的是<html>
標簽;
document.body代表的是<body>
標簽;
5、分析上述事件流示例代碼及輸出結果
在標准的“DOM2級事件”中規定,事件流首先是經過事件捕獲階段,接着是處於目標階段,最后是事件冒泡階段。示意圖如下所示:
首先在事件捕獲過程中,document對象首先接收到click事件,然后事件沿着DOM樹依次向下,一直傳播到事件的實際目標,就是id為btn的a標簽。
接着在事件冒泡過程中,事件開始時由最具體的元素(a標簽)接收,然后逐級向上傳播到較為不具體的節點(document)。
需要注意的點:由於老版本的瀏覽器不支持事件捕獲,因此在實際開發中需要使用事件冒泡,在由特殊需要時再使用事件捕獲。
補充:
1、IE中的事件流只支持“事件冒泡”,但是版本到了IE9+以后,實現了“DOM2級事件”,也就是說IE9+以后也可以在捕獲階段對元素進行相應的操作。
2、在DOM事件流中,實際的目標在“捕獲階段”不會接收到事件。而是在“處於目標階段”被觸發,並在事件處理中被看成“冒泡階段”的一部分。然后,“冒泡階段”發生,事件又傳播回文檔。
3、jquery不支持事件捕獲階段,只支持事件冒泡。
6、jQuery的事件流程導圖
jQuery的事件流程導圖地址:https://www.processon.com/view/link/5ad1c48de4b0b74a6dd65426
七、jQuery的事件對象和事件冒泡
1、什么是事件冒泡
在一個對象上觸發某類事件(比如單擊onclick事件),如果此對象定義了此事件的處理程序,那么此事件就會調用這個處理程序,如果沒有定義此事件處理程序或者事件返回true,那么這個事件會向這個對象的父級對象傳播,從里到外,直至它被處理(父級對象所有同類事件都將被激活),或者它到達了對象層次的最頂層,即document對象(有些瀏覽器是window)。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <button>點擊</button> </div> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> $('button').click(function () { // 冒泡:在頁面上僅點擊了button。先觸發了button的alert,后觸發了box的alert。因此冒泡影響了頁面效果。 // 需要阻止冒泡 alert('button事件觸發了'); }) $('#box').click(function () { alert('22222'); }) </script> </html>
在上例中,在頁面上僅點擊了button。先是觸發了button的alert,隨后又自動觸發了box的alert,由此可以看出冒泡激活我們本來不想激活的事件,影響了頁面效果。所以必要時,要阻止事件冒泡
2、事件對象的常見屬性
// ev事件對象 $('.p1').click(function (ev) { // 事件類型、事件屬性 console.log(ev.type); //獲取事件的類型:click console.log(ev.target); //獲取事件發生的DOM對象:<p class:'p1'></p console.log(ev.pageX); //獲取到光標相對於頁面的x的坐標: 50 console.log(ev.pageY); //獲取到光標相對於頁面的y的坐標: 63 console.log(ev.which); //鼠標單擊事件中獲取到鼠標的鍵,鍵盤事件中獲取鍵盤的按鍵: 1
3、事件冒泡的常用事件
(1)阻止事件冒泡:e.stopPropagation()方法
(2)阻止默認行為:e.preventDefault()方法
(3)return false在jQuery中可以阻止事件冒泡和默認事件;jQuery不支持事件捕獲。
$('a').click(function (ev) { //方法一:同時阻止默認事件和冒泡事件 ev.preventDefault(); // 阻止默認事件 ev.stopPropagation(); // 再阻止冒泡事件 alert('不再跳轉頁面'); // 方法二: return false; // 這個可以阻止a標簽的默認事件和冒泡事件 })
jQuery的事件對象和事件冒泡示例代碼如下:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #box{ width: 200px; height: 200px; background: gray; } p{ width: 100px; height: 100px; background: red; } </style> </head> <body> <div id="box"> <p class="p1"></p> <a href="https://www.luffycity.com">luffy</a> </div> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> //入口函數事件 $(function () { // ev事件對象 $('.p1').click(function (ev) { // 事件類型、事件屬性 console.log(ev.type); //獲取事件的類型:click console.log(ev.target); //獲取事件發生的DOM對象:<p class:'p1'></p console.log(ev.pageX); //獲取到光標相對於頁面的x的坐標: 50 console.log(ev.pageY); //獲取到光標相對於頁面的y的坐標: 63 console.log(ev.which); //鼠標單擊事件中獲取到鼠標的鍵,鍵盤事件中獲取鍵盤的按鍵: 1 alert('當前按鈕事件觸發了'); // 常用的事件 方法:1.阻止事件冒泡 2.阻止默認事件 // 1.阻止事件冒泡,不再傳到div中 ev.stopPropagation(); }) $('#box').click(function () { alert('#box盒子事件觸發了'); }) $('a').click(function (ev) { // 阻止a標簽的默認事件 ev.preventDefault(); // 再阻止冒泡 ev.stopPropagation(); alert('不再跳轉頁面'); // 方法二: return false; // 這個可以阻止a標簽的默認事件和冒泡事件 }) }) </script> </html>
八、事件的綁定和移除
1、給當前dom添加事件有兩種方法
// 方式一:給當前dom元素添加click事件 $('#box').click(fn); // 方式二:給當前的dom元素綁定事件 bind() // 語法:jquery對象.bind('事件類型',fn) $('#box').bind('click mouseenter', function () { alert('事件被綁定了') })
2、詳解事件和函數綁定到元素——bind()綁定方法
語法:$(selector).bind(event,data,function)
參數:第一個參數是事件類型,常用click,blur,hover等;多個事件類型可以通過將每個空格分隔開來一次綁定。
可以通過傳遞事件類型/處理程序對的對象來同時綁定多個事件處理程序
第二個參數是可選參數,作為envet.data屬性值傳遞給事件對象的額外數據對象
第三個參數是用來綁定的處理函數
function add() { console.log('click'); } function add2() { console.log('mouse-over') } // 給jquery對象添加不同的事件 $('#box').bind({ 'click': add, 'mouseenter':add2 })
完成上述代碼后,點擊盒子則執行add函數,移入盒子則執行add2函數。
3、移除事件——unbind()
語法:unbind(type,fn)
第一個參數:事件類型。如果不寫參數,移除所有的事件:
// 如果沒有參數表示移除所有事件 $('#box').unbind();
第二個參數:將要移除的函數
$( "#foo").unbind( "click" ,function(){})
4、事件代理
所謂事件就是onclick\onmouseover\onmouseout等事件,委托就是讓別人來做。這個事件本來是加在某些元素上,卻加到別人身上來完成這個事件。
原理:利用冒泡的原理,把事件加到父級上,觸發執行效果。
事件代理(委托)使用情景:
(1)為DOM中的很多元素綁定相同事件:事件注冊在祖先級元素上,代理其子級元素。可以減少事件注冊數量,節約內存開銷,提高性能。
(2)為DOM中尚不存在的元素綁定事件:對js動態添加的子元素可自動綁定事件。
事件代理作用:
(1)性能比較好;(2)針對新創建的元素,直接可以擁有事件。
事件源:跟this作用一樣(不用看指向問題,誰操作的就是誰),event對象的。
// 后續添加的事件不能發生在未來==》動態生產的元素不能直接添加對象,里面的事件也不能發生==》事件代理 $('body').append('<div style="width: 200px;height: 300px;background-color: yellow">哈哈哈哈</div>') //綁定自定義的事件 $('button').bind('myclick',function (ev,a,b,c) { alert(111); alert(a); // 1 alert(b); // 2 alert(c); // 3 }) // 觸發自定義的事件 $('button').trigger('myclick',[1,2,3])
動態添加元素div,綁定自定義事件后必須運用trigger()方法來觸發自定義事件。
事件綁定和移除的示例代碼如下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件綁定和移除</title> <style type="text/css"> #box { width: 200px; height: 200px; background: red; } </style> </head> <body> <div id="box"> </div> <button>按鈕</button> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function () { // 給當前dom元素添加click事件:方式一如下 // $('#box').click(fn); // 方式二:給當前的dom元素綁定事件 bind() // 語法:jquery對象.bind('事件類型',fn) // $('#box').bind('click mouseenter', function () { // alert('事件被綁定了') // }) function add() { console.log('click'); } function add2() { console.log('mouse-over') } // 給jquery對象添加不同的事件 $('#box').bind({ 'click': add, 'mouseenter':add2 }) // 事件移除 unbind() setTimeout(function () { // 如果沒有參數表示移除所有事件 // $('#box').unbind(); $('#box').unbind('click'); },3000) // 后續添加的事件不能發生在未來==》動態生產的元素不能直接添加對象,里面的事件也不能發生==》事件代理 $('body').append('<div style="width: 200px;height: 300px;background-color: yellow">哈哈哈哈</div>') //綁定自定義的事件 $('button').bind('myclick',function (ev,a,b,c) { alert(111); alert(a); // 1 alert(b); // 2 alert(c); // 3 }) // 觸發自定義的事件 // $('button').trigger('myclick',[1,2,3]) }) </script> </html>
九、事件代理詳解(on/delegate/bind)
事件代理:自己完成不了當前的點擊事件,交給父級元素來做這件事情。
上一節中用bind函數將click事件綁定到對象上,從而實現了事件代理。還有其他事件代理方法:on和delegate等。
on方法和delegate方法基本相同,區別僅在於參數:
on(綁定事件,選擇器,回調函數) delegate(綁定的選擇器,綁定事件,回調函數)
on方法語法如下:
父級.on('事件名字','點擊當前的標簽元素',fn)
.on在選擇元素上綁定一個或多個事件:
//事件代理 自己完成不了當前的點擊事件,交給父級元素來做這件事情 //父級.on('事件名字','點擊當前的標簽元素',fn) 第二個參數其實是選擇器 // $('ul').on('click','li',function () { $('ul').on('click','#namei,.luffy',function () { // 綁定多個選擇器:注意用逗號分隔 console.log(this); })
事件代理示例代碼如下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件代理</title> </head> <body> <ul> <li class="luffy">路飛</li> <li>路飛</li> <li>路飛</li> </ul> </body> <script src="jquery-3.3.1.js"></script> <script type="text/javascript"> // 文檔加載 $(document).ready(function () { // ul下的每個li 先點擊 // $('ul>li').bind('click',function () { // console.log($(this)); // 點擊li會在控制台打印出對應的html標簽信息 // }) //另一種寫法: // $('ul>li').click(function () { // console.log($(this)); // }) //事件代理 自己完成不了當前的點擊事件,交給父級元素來做這件事情 //父級.on('事件名字','點擊當前的標簽元素',fn) 第二個參數其實是選擇器 // $('ul').on('click','li',function () { $('ul').on('click','#namei,.luffy',function () { // 綁定多個選擇器:注意用逗號分隔 console.log(this); }) // 后來添加的元素 $('ul').append('<li>娜美</li>'); $('ul').append('<a id="namei">娜美</a>') // 其他事件代理方法:delegate(綁定的選擇器,綁定事件,回調函數) // on(綁定事件,選擇器,回調函數) 注意兩者主要是參數的區別 }) </script> </html>
$('ul').on('click','#nami, .luffy'.function) () {} 是綁定了兩個選擇器,兩個選擇器用逗號分隔。進在點擊id=namei和class=luffy的元素時會在控制台打印相關信息:<li class="luffy">路飛</li> 、 <a id="namei">娜美</a>。
十、鼠標事件
1、鼠標點擊
click():鼠標單擊觸發事件,參數可選(data,fn)
// 點擊事件 $('#box').click(function () { console.log('click'); })
dbclick():鼠標雙擊觸發
// 雙擊事件 dblclick $('#box').dblclick(function () { console.log('dbclick'); })
mousedown():鼠標按下觸發事件
// 鼠標按下不松開 $('#box').mousedown(function () { console.log('mousedown'); })
mouseup():鼠標彈起觸發事件
// 鼠標松開觸發 $('#box').mouseup(function () { console.log('mouseup'); })
2、鼠標移動
mouseover():鼠標移入觸發事件;mouseout():鼠標移出觸發事件。mouseover()/out()鼠標指針穿過/離開被選元素或者當前元素的子元素,會觸發事件。
//被選元素和子元素被選中時會觸發函數 移入移出 $('#box').mouseover(function () { console.log('mouseover') }) $('#box').mouseout(function () { console.log('mouseout') })
mouseenter():鼠標進入觸發事件;mouseleave():鼠標離開觸發事件。mouseenter()/leave()鼠標指針只在穿過/離開被選元素觸發事件。
// 鼠標指針只在穿過/離開被選元素觸發事件 $('#box').mouseenter(function () { console.log('mouseenter'); }) $('#box').mouseleave(function () { console.log('mouseleave'); })
mousemove():鼠標移動觸發事件。實時監聽鼠標移動事件(元素范圍內) ————常用於做拖拽
// 實時監聽鼠標移動事件(元素范圍內) ————常用於做拖拽 $('#box').mousemove(function () { console.log('mousemove'); })
3、鼠標聚焦/失焦
focus():鼠標聚焦觸發事件;blur():鼠標失焦觸發事件。
// 鼠標聚焦/失去焦點觸發事件(不支持冒泡) // 獲焦:文本輸入框邊框變藍色 $('input[type=text]').focus(function () { console.log($(this).val()); }) // 在文本框修改123為其他字符,然后在input元素外點擊,完成失焦,console打印出修改后的字符串 $('input[type=text]').blur(function () { console.log($(this).val()); })
4、鍵盤按鍵
keydown():鍵盤按鍵按下觸發;keyup():鍵盤按鍵彈起觸發。
// keydown鍵盤按下 $('input[type=password]').keydown(function () { console.log($(this).val()) // 最開始按下1是取的是空值 }) $('input[type=password]').keyup(function () { console.log($(this).val()) // 最開始按下1松開,取到了1 })
在這里需要注意,點擊輸入框用鍵盤輸入時,按下取一次值,松開取一次值(這一次包含剛剛按下的鍵的值)。
十一、表單事件
1、change():表單元素發生改變時觸發事件
//change()事件————表單元素發生改變時觸發事件 //此事件僅限於input元素、textarea框、select元素。 //對於選擇框,復選框和單選按鈕,當用戶使用鼠標進行選擇時,會立即觸發事件。但對於其他元素類型,事件將延遲到元素失去焦點 $('select').change(function(){ console.log($('select option:selected').text()); $('.show').text($('select option:selected').text()); })
2、select():文本元素發生改變時觸發事件
// select()事件————文本元素發生改變時觸發事件 // 僅限於用在input type=text 或 textarea 表單元素 $('#other').select(function () { console.log($(this).val()); })
3、submit():表單元素發生改變時觸發事件
// form表單和服務端有很大的掛鈎:form表單有默認的submit行為,當對input type=submit按鈕點擊的時候會觸發form的默認action行為, // 此時可以調用 jquery的submit方法通過e.preventDefault()來阻止默認事件,這樣我們就能動態的跟服務端來發送數據了 $('form').submit(function (ev) { // alert(1111); // 觸發submit事件彈出1111,再觸發form表單的默認行為跳轉到路飛官網 // 阻止默認事件 ev.preventDefault(); alert(1111); // 只會觸發submit事件彈出1111 })
表單事件代碼示例:

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Page Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .show{ color: red; } </style> </head> <body> <form action="https://www.luffycity.com"> <select name="sweets" multiple=''> <option value="">巧克力</option> <option value="" selected=''>糖果</option> <option value="">焦糖</option> <option value="" selected=''>曲奇餅</option> <option value="">燒餅</option> <option value="">麥香餅</option> <option value="">曲奇餅2</option> </select> <input type="text" value="hello" id='target'> <input type="submit" value="Luffy"/> <input type="button" value="按鈕" /> </form> <input id="other" type="text" value="Trigger the handler"> <div class="show"></div> <script src="./jquery-3.3.1.js"></script> <script type="text/javascript"> $(function() { //change()事件————表單元素發生改變時觸發事件 //此事件僅限於input元素、textarea框、select元素。 //對於選擇框,復選框和單選按鈕,當用戶使用鼠標進行選擇時,會立即觸發事件。但對於其他元素類型,事件將延遲到元素失去焦點 $('select').change(function(){ console.log($('select option:selected').text()); $('.show').text($('select option:selected').text()); }) // select()事件————文本元素發生改變時觸發事件 // 僅限於用在input type=text 或 textarea 表單元素 $('#other').select(function () { console.log($(this).val()); }) // form表單和服務端有很大的掛鈎:form表單有默認的submit行為,當對input type=submit按鈕點擊的時候會觸發form的默認action行為, // 此時可以調用 jquery的submit方法通過e.preventDefault()來阻止默認事件,這樣我們就能動態的跟服務端來發送數據了 $('form').submit(function (ev) { // alert(1111); // 觸發submit事件彈出1111,再觸發form表單的默認行為跳轉到路飛官網 // 阻止默認事件 ev.preventDefault(); alert(1111); // 只會觸發submit事件彈出1111 }) }) </script> </body> </html>