定義兩個(gè)函數(shù)
html
<body>
<ul>
<li id="item1">選項(xiàng)1</li>
<li id="item2">選項(xiàng)1</li>
<li id="item3">選項(xiàng)1</li>
<li id="item4">選項(xiàng)1</li>
<li id="item5">選項(xiàng)1</li>
</ul>
</body>
function getsiblings (node) {
var allChildren = node.parendNode.children
var array = {length: 0}
for (let i=0; i < allChildren.length; i++) {
if (allChildren[i] !== node) { // 此處有一個(gè)點(diǎn),就是少用 == 和弹砚!=
array[length] = allChildren[i]
array.length += 1
}
}
return array
}
function addClass (node, classes) {
for(let key in classes) {
let value = classes[key]
let mothedName = value ? 'add' : 'remove'
node.classList[mothedName](key)
}
}
getSiblings(item3)
addClass(item3, {'a': true, 'b' : false})
此時(shí)上面已經(jīng)有了兩個(gè)可以使用的函數(shù)无切,分別有不同的用途。當(dāng)你的函數(shù)庫(kù)發(fā)展到一定的數(shù)量時(shí)啡省,我們需要給他們一個(gè)名字娜睛,把他們統(tǒng)一起來(lái)。這時(shí)候出現(xiàn)的命名空間的概念:它表示著一個(gè)標(biāo)識(shí)符(identifier)的可見(jiàn)范圍卦睹。一個(gè)標(biāo)識(shí)符可在多個(gè)名字空間中定義微姊,它在不同名字空間中的含義是互不相干的。這樣分预,在一個(gè)新的名字空間中可定義任何標(biāo)識(shí)符兢交,它們不會(huì)與任何已有的標(biāo)識(shí)符發(fā)生沖突,因?yàn)橐延械亩x都處于其他名字空間中笼痹。
命名空間就可以讓相同的變量名不沖突配喳。我們不希望函數(shù)庫(kù)的函數(shù)命名和用戶的其他變量沖突。
使用命名空間可以讓人知道你的庫(kù)叫什么凳干,而且不會(huì)覆蓋用戶的同名變量
window.myDom = {}
myDom.getSiblings = function (node) {
var allChildren = node.parendNode.children
var array = {length: 0}
for (let i=0; i < allChildren.length; i++) {
if (allChildren[i] !== node) { // 此處有一個(gè)點(diǎn)晴裹,就是少用 == 和!=
array[length] = allChildren[i]
array.length += 1
}
}
return array
}
myDom.addClass() = function (node, classes) {
for(let key in classes) {
let value = classes[key]
let mothedName = value ? 'add' : 'remove'
node.classList[mothedName](key)
}
}
myDom.getSiblings(item3)
myDom.addClass(item3, {'a': true, 'b': false})
上面的代碼還有一個(gè)問(wèn)題救赐,就是每次都要輸入myDom涧团。我現(xiàn)在想直接
item3.getSiblings()
。
Node.prototype.getSiblings = function () {
var allChildren = this.parendNode.children
var array = {length: 0}
for (let i=0; i < allChildren.length; i++) {
if (allChildren[i] !== this) { // 此處有一個(gè)點(diǎn)经磅,就是少用 == 和泌绣!=
array[length] = allChildren[i]
array.length += 1
}
}
return array
}
item3.getSiblings() // 此時(shí)就可以這樣執(zhí)行
Node.prototype.addClass = function (classes) {
for(let key in classes) {
let value = classes[key]
let mothedName = value ? 'add' : 'remove'
this.classList[mothedName](key)
}
}
item3.addClass({a: true, b: false}) // 不知道this請(qǐng)使用call()方法
上面的代碼需要說(shuō)明的是,item3是Element構(gòu)造函數(shù)的實(shí)例预厌,Element繼承Node阿迈。所以在Node.prototype上的方法,item3可以直接調(diào)用到(通過(guò)原型鏈)轧叽。
還有一個(gè)this的問(wèn)題苗沧。上面的item3.getSiblings()
調(diào)用方式刊棕,很多人并不知道為什么this是item3。
所以我們每次在調(diào)用函數(shù)時(shí)應(yīng)該使用call()方法調(diào)用
call()方法的第一個(gè)參數(shù)就是this值待逞。 請(qǐng)使用call()方法調(diào)用函數(shù)
上面的代碼還是有問(wèn)題的甥角,我們直接在prototype中添加方法,用戶可能會(huì)寫(xiě)相同名字的變量到prototype中识樱,導(dǎo)致覆蓋嗤无。所以這種也并不是好辦法。
window.JQuery = function (nodeOrSelector) {
let node
if (typeof nodeOrSelector === "string") {
document.querySelector(nodeOrSelector)
} else {
node = nodeOrSelector
}
return {
getSiblings: function () {
var allChildren = this.parendNode.children
var array = {length: 0}
for (let i=0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[length] = allChildren[i]
array.length += 1
}
}
return array
}
addClass: function (classes) {
for(let key in classes) {
let value = classes[key]
let mothedName = value ? 'add' : 'remove'
node.classList[mothedName](key)
}
}
}
}
JQuery('#item3').getSiblings()
JQuery('#item3').addClass({a: true, b: false})
升級(jí)版
window.JQuery = function (nodeOrSelector) {
let nodes = {}
if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSeletor) // 這里也是偽數(shù)組牺荠,但是原型鏈上會(huì)指向Node
for (let i = 0; i < temp.length; i++) { // 此時(shí)是為了得到純凈的偽數(shù)組翁巍,即直接繼承自O(shè)bject
nodes[i] = temp[i]
}
nodes.length = temp.length
} else if (nodeOrSelector intanceof Node) {
nodes = {
0: nodeOrSelector,
length: 1
}
}
nodes.addClass = function (classes) {
for (let key in classes) {
let value = classes[key]
let methodName = value ? 'add' : 'remove'
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList[methodName](key)
}
}
}
nodes.text = function (text) {
if (text === undefined) { // 判斷是否傳值驴一,沒(méi)有傳值表示想獲取標(biāo)簽內(nèi)的值休雌。
let texts = []
for (let i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent)
}
return texts
} else { // 表示設(shè)置標(biāo)簽內(nèi)的值
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
}
return nodes
}
JQuery('ul > li').addClass({blue: true})
JQuery('ul > li').text('hi')
封裝一個(gè)ajax
window.JQuery.ajax = function ({url,method,body}) {
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest()
request.open(method, url)
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 300) {
resolve.call(undefined, 'success')
}else if (request.status >= 400) {
reject.call(undefined, 'fail')
}
}
}
request.send(body)
})
}
window.JQuery.ajax({
url: '/xxx',
method: 'get'
}).then(
(text) => {console.log(text)},
(text) => {console.log(text)}
)