實(shí)現(xiàn)目的
本文的目的是通過(guò)模仿jQuery實(shí)現(xiàn)兩個(gè)簡(jiǎn)化的jQuery的API:
$nodes.addClass(classes)
$nodes.setText('text')
$nodes
是我們模仿jQuery建立的一個(gè)簡(jiǎn)化版的jQuery對(duì)象漫玄。$nodes.addClass(classes)
給所有的$nodes
添加指定的class坡倔。
其中參數(shù) classes
可以是一個(gè)字符串表示一個(gè)樣式類名兵琳,也可以是個(gè)數(shù)組柳刮,表示多個(gè)樣式類名懊昨,同時(shí)添加多個(gè)classes爽蝴。
-
$nodes.setText('text')
把所有的$nodes
的textcontent
變?yōu)橹付ǖ奈谋緝?nèi)容急波。參數(shù)
'text'
是一個(gè)字符串从铲。
驗(yàn)證方法
為了驗(yàn)證API的準(zhǔn)確性,我們要求API能實(shí)現(xiàn)以下功能:
var $div = $('div') // 接收一個(gè)包含CSS選擇器的字符串澄暮,創(chuàng)建一個(gè)由簡(jiǎn)化版jQuery包裝的DOM元素
$div.addClass('red') // 可將所有 div 的 class 添加一個(gè) red
$div.setText('hi') // 可將所有 div 的 textContent 變?yōu)?hi
$div.addClass(['small', 'circle']) // 可將所有 div 的 class 同時(shí)添加一個(gè) small 和 circle
HTML 代碼
<!DOCTYPE html>
<html>
<head>
<title>jQuery API Demo</title>
<script src="./jQuery-API.js"></script>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div class="demo"></div>
<div class="demo"></div>
<div class="demo"></div>
<div class="demo"></div>
</body>
</html>
CSS 代碼
.demo {
width: 400px;
height: 300px;
border: 10px solid black;
font-size: 20px;
display: inline-block;
}
.red {
background: red;
}
.circle {
border-radius: 50%;
}
.small {
width: 200px;
height: 150px;
}
命名空間和返回對(duì)象結(jié)構(gòu)統(tǒng)一
首先我們要寫一個(gè)函數(shù)名段,使得傳入函數(shù)的節(jié)點(diǎn)或者是一個(gè)包含CSS選擇器的字符串,都返回一個(gè)經(jīng)過(guò)我們包裝過(guò)的一個(gè)DOM對(duì)象泣懊,這個(gè)新對(duì)象必須保持形式統(tǒng)一伸辟,并且同時(shí)含有 addClass
和 setText
兩個(gè)屬性,這樣我們就能直接在新對(duì)象調(diào)用我們所實(shí)現(xiàn)的兩個(gè)API馍刮。
window.jQuery = function(nodeOrSelector) {
let nodes = {}
if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector)
for (let i = 0; i < temp.length; i++) {
nodes[i] = temp[i]
}
nodes.length = temp.length
} else if (nodeOrSelector instanceof Node) {
nodes = {
0: nodeOrSelector,
length: 1
}
}
nodes.addClass = function(classes) {
}
nodes.setText = function(text) {
}
return nodes
}
window.$ = jQuery
為了使得通過(guò)包含CSS選擇器的字符串返回得到的對(duì)象保持純凈(不包含DOM對(duì)象的原型鏈)信夫,我們通過(guò)遍歷
document.querySelectorAll(nodeOrSelector)
得到一個(gè)純凈的偽數(shù)組。-
同時(shí)為了使得由字符串和節(jié)點(diǎn)傳入返回得到的對(duì)象保持結(jié)構(gòu)一致卡啰,我們把由傳入節(jié)點(diǎn)返回的對(duì)象也包裝成一個(gè)純凈的偽數(shù)組忙迁。
nodes = { 0: nodeOrSelector, length: 1 }
-
同時(shí)我們所返回的對(duì)象也必須含有
addClass
和setText
屬性。nodes.addClass = function(classes) { } nodes.setText = function(text) { }
-
為了方便書寫碎乃,使得
$
縮寫來(lái)返回得到一個(gè)jQuery對(duì)象window.$ = jQuery
addClass屬性
為了簡(jiǎn)化操作姊扔,我們只在這里考慮兩種參數(shù)類型。
-
字符串
表示一個(gè)指定添加的class名稱
-
數(shù)組
數(shù)組的value表示一組指定添加的class名稱
所以我們需要先判斷傳入的參數(shù)是哪種類型
nodes.addClass = function(classes) {
if (classes instanceof Array) {
classes.forEach((value) => {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value)
}
})
} else if (typeof classes === 'string') {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(classes)
}
}
}
- 對(duì)于數(shù)組我們首先調(diào)用數(shù)組的
forEach
遍歷classes
再通過(guò)for
循環(huán)遍歷nodes
把所有樣式類名添加到所有nodes
中梅誓。 - 對(duì)于字符串恰梢,我們直接使用
for
循環(huán)遍歷nodes
。
setText屬性
nodes.setText = function(text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
我們通過(guò) for
循環(huán)遍歷 nodes
調(diào)用DOM元素的 textContent
函數(shù) 給所有 nodes
添加指定的文本內(nèi)容
驗(yàn)證結(jié)果
我們?cè)跒g覽器的console界面輸入以下代碼
var $div = $('div') // 接收一個(gè)包含CSS選擇器的字符串梗掰,創(chuàng)建一個(gè)由簡(jiǎn)化版jQuery包裝的DOM元素
$div
返回得到了一個(gè)純凈的偽數(shù)組嵌言,4個(gè)div,length
屬性 以及我們需要調(diào)用的2個(gè)函數(shù)addClass
和 setText
及穗。
$div.addClass('red') // 可將所有 div 的 class 添加一個(gè) red
CSS 代碼:
.red {
background: red;
}
我們可以看到所有div的背景變紅了摧茴。
$div.setText('hi') // 可將所有 div 的 textContent 變?yōu)?hi
我們可以看到所有div都被添加了文本內(nèi)容:hi
。
$div.addClass(['small', 'circle']) // 可將所有 div 的 class 同時(shí)添加一個(gè) small 和 circle
CSS 代碼:
.circle {
border-radius: 50%;
}
.small {
width: 200px;
height: 150px;
}
我們可以看到所有div的class同時(shí)被添加了 small 和 circle埂陆。
完