這也是一個(gè)練習(xí)扔亥,就是一般電商購(gòu)物車的全選,另外加了個(gè)反選(貌似有反選功能的購(gòu)物車不多,倒是windows資源管理器有反選功能)
先說全選:
- 當(dāng)4行商品都被勾選上時(shí)埃碱,“全選”自動(dòng)被勾選上;當(dāng)有商品沒有被勾選時(shí)弱卡,“全選”自動(dòng)被取消乃正。
- 當(dāng)4行商品商品并沒有被全部勾選上時(shí),勾選“全選”可以讓4行商品全部被勾選上婶博;
- 當(dāng)“全選”處于被勾選狀態(tài)時(shí)瓮具,取消“全選”的勾選,所有的商品都取消勾選凡人。
梳理好需求名党,我們先用HTML和CSS把這個(gè)表單畫出來,代碼如下:
<html>
<head>
<meta charset="utf-8">
<title>全選2</title>
<style type="text/css">
.wrap{
margin-left: 500px;
margin-top: 200px;
}
table{
border-collapse:collapse;
}
th{
border:1px solid black;
height: 45px;
}
td{
border:1px solid black;
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<div class="wrap">
<table cellspacing="0" cellpadding="14">
<thead>
<tr>
<th>
<input type="checkbox" id="selectAll" onclick="funcAll()">
</th>
<th>商品</th>
<th>價(jià)格</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox" class="selectOne" onclick="funcOne()">
</td>
<td>iPhone X</td>
<td>8000</td>
</tr>
<tr>
<td>
<input type="checkbox" class="selectOne" onclick="funcOne()">
</td>
<td>iPad pro</td>
<td>5000</td>
</tr>
<tr>
<td>
<input type="checkbox" class="selectOne" onclick="funcOne()">
</td>
<td>iPad air</td>
<td>2000</td>
</tr>
<tr>
<td>
<input type="checkbox" class="selectOne" onclick="funcOne()">
</td>
<td>Apple watch</td>
<td>2000</td>
</tr>
</tbody>
</table>
<input type="button" id="backwardOption" value="反選" onclick="funcBackward()">
</div>
</body>
</html>
這里我已經(jīng)把鼠標(biāo)點(diǎn)擊事件的函數(shù)命名好了挠轴,全選叫“funcAll()”传睹,單選叫“funcOne()”,反選叫“funcBackward()”岸晦。CSS部分主要給表單加上邊框欧啤,同時(shí)交接處邊框融合,基本就是最樸素的樣子启上。
先說第2條和第3條需求邢隧,邏輯相對(duì)簡(jiǎn)單:
用DOM方法分別獲取全選和單選的“input”元素,全選只有一個(gè)冈在,直接用getElementById()就可以了(已經(jīng)提前設(shè)置好id)倒慧,而單選有四個(gè),用getElementByClassName()來獲劝(已經(jīng)提前設(shè)置好class)纫谅,當(dāng)然獲取到的是一個(gè)數(shù)組。
講獲取到的元素都賦值給變量溅固,然后用for循環(huán)遍歷數(shù)組付秕,將全選的這個(gè)變量的checked屬性賦值給每個(gè)單選的變量的checked屬性。
此時(shí)侍郭,已經(jīng)同時(shí)解決2和3盹牧,代碼如下:
function funcAll(){
var selectAll = document.getElementById('selectAll');
var selectOnes = document.getElementsByClassName('selectOne');
for (var i = 0; i < selectOnes.length; i++) { //循環(huán)遍歷俩垃,把全選框的值賦給每個(gè)單選框
selectOnes[i].checked = selectAll.checked;
}
}
接下來說第1條:“當(dāng)4行商品都被勾選上時(shí),“全選”自動(dòng)被勾選上汰寓;當(dāng)有商品沒有被勾選時(shí)口柳,“全選”自動(dòng)被取消∮谢”
在這里跃闹,“全選”的狀態(tài)類似在監(jiān)聽其他所有按鈕,一旦有變化毛好,隨之變化望艺。所以這個(gè)邏輯要寫到每行商品單選按鈕的鼠標(biāo)點(diǎn)擊事件里。
我設(shè)置了一個(gè)變量isAllChecked作為橋梁肌访,初始狀態(tài)將isAllChecked定義為true找默,循環(huán)遍歷每個(gè)單選按鈕,一旦檢測(cè)到有單選按鈕沒被勾選吼驶,就將isAllChecked置為false惩激,跳出循環(huán),并將isAllChecked的值賦給全選按鈕蟹演。
這樣一來风钻,只要有一個(gè)單選按鈕沒被選中,就會(huì)將全選也變成未選中狀態(tài)酒请。骡技,代碼如下:
function funcOne(){
var selectAll = document.getElementById('selectAll'); //函數(shù)作用域,所以得再定義一遍
var selectOnes = document.getElementsByClassName('selectOne');
var isAllChecked = true; //定義一個(gè)變量作為橋梁來控制全選按鈕
for (var i = 0; i < selectOnes.length; i++) {
if (selectOnes[i].checked === false) {
isAllChecked = false;
break;
}
}
selectAll.checked = isAllChecked;
}
再來說說反選
- 點(diǎn)擊反選按鈕羞反,所有的單選按鈕狀態(tài)取反:選中的變成未選中布朦,未選中的變成選中
- 點(diǎn)擊反選,造成的結(jié)果昼窗,仍然能夠讓全選符合之前的邏輯是趴。
第1條其實(shí)很好實(shí)現(xiàn),點(diǎn)擊反選按鈕時(shí)膏秫,循環(huán)遍歷4個(gè)單選按鈕,將每個(gè)元素對(duì)應(yīng)的checked屬性取反即可做盅。
但是缤削,我們?cè)谇懊鎸?shí)現(xiàn)的全選監(jiān)聽所有單項(xiàng),實(shí)際上是在每個(gè)單選按鈕的點(diǎn)擊事件里實(shí)現(xiàn)的吹榴,也就是說亭敢,如果我們不通過點(diǎn)擊單選按鈕來改變單選按鈕的狀態(tài),全選實(shí)際上是監(jiān)聽不到全局的图筹。
所以帅刀,我們可以把監(jiān)聽這部分的代碼再寫到反選的鼠標(biāo)點(diǎn)擊函數(shù)里去让腹,最后的代碼如下:
var selectAll = document.getElementById('selectAll'); //函數(shù)作用域,所以得再定義一遍
var selectOnes = document.getElementsByClassName('selectOne');
for (var i = 0; i < selectOnes.length; i++) {
selectOnes[i].isAllChecked = !selectOnes[i].checked;
}
function funcOne(){};
var isAllChecked = true; //定義一個(gè)變量作為橋梁來控制全選按鈕
for (var i = 0; i < selectOnes.length; i++) {
if (selectOnes[i].checked === false) {
isAllChecked = false;
break;
}
}
selectAll.checked = isAllChecked;
}
最終的效果如下: