上一篇文章 從封裝函數到實現簡易版自用jQuery (一) 已經介紹瞭如何實現基本功能和封裝成本身的庫,這篇文章着重講對本身 API 功能的拓展,使其更強大。node
如下是基於第一篇文章,在本次練習中要用到的代碼,以 addClass( ) 爲例進行拓展。bash
<ul>
<li id="item1">item1</li>
<li id="item2">item2</li>
<li id="item3">item3</li>
<li id="item4">item4</li>
<li id="item5">item5</li>
</ul>
.red{
color:red;
}
window.simpleTools = function(node){
return{
addClass:function(classes){
classes.forEach((value) =>
node.classList.add(value));
}
};
};
複製代碼
解決方案:函數
加個類型判斷來解決吧!爲了讓咱們的代碼更加語義化,傳來的參數由 node 更名爲 nodeOrSelector,在函數內再定義一個 node 變量, 若是傳參是選擇器,經過 document.querySelector()
來找到相應的節點,賦值給 node; 若是傳參不是選擇器,直接賦值給 node 存起來。post
var node;
if(typeof nodeOrSelector === 'string'){
node = document.querySelector(nodeOrSelector);
}else{
node = nodeOrSelector;
}
複製代碼
測試運行:測試
var nodeTest = simpleTools('#item3');
nodeTest.addClass(['red']);
console.log(document.querySelectorAll('#item3'));
複製代碼
解決方案:優化
document.querySelector( )
改爲 document.querySelectorAll( )
, 此時變量 node 變成 nodes 對象。window.simpleTools = function(nodeOrSelector){
var nodes = {};
if(typeof nodeOrSelector === 'string'){
nodes = document.querySelectorAll(nodeOrSelector);
}else{
nodes = nodeOrSelector;
}
return{
addClass:function(classes){
classes.forEach((value) =>{
for(var i = 0;i < nodes.length;i++){
nodes[i].classList.add(value);
}
});
}
};
};
複製代碼
測試運行:ui
var nodeTest = simpleTools('ul>li');
nodeTest.addClass(['red']);
console.log(document.querySelectorAll('ul>li'))
複製代碼
var nodeTest2 = simpleTools('#item3');
nodeTest2.addClass(['red']);
console.log(document.querySelectorAll('#item3'))
複製代碼
如今的 nodes 是一個鏈接着 NodeList.prototype 的對象,個人原型鏈想直接是 Object.prototype, 怎麼辦呢?spa
解決方案:prototype
藉助一個臨時變量,經過循環遍歷獲得一個純淨的對象。3d
window.simpleTools = function(nodeOrSelector){
var nodes = {};
if(typeof nodeOrSelector === 'string'){
var temp = document.querySelectorAll(nodeOrSelector);
for(var i =0 ;i<temp.length;i++){
nodes[i] = temp[i];
}
nodes.length = temp.length;
}else if(nodeOrSelector instanceof Node){
nodes = {
0 :nodeOrSelector,
length :1
};
}
return nodes; // 只看nodes的變化,暫時先忽略addClass( )方法
};
複製代碼
若是是多個選擇器,遍歷並存儲,不要忘記了nodes.length
哦。若是是一個節點,也須要把 nodeOrSelector 構造出和上面分支同樣的形式存到 node 對象中。如今不管是多個選擇器仍是一個節點,都轉化成了只連接 Object.prototype 的對象。
測試運行:
var nodeTest = simpleTools('#item3');
console.log(nodeTest);
複製代碼
var nodeTest2 = simpleTools('ul>li');
console.log(nodeTest2);
複製代碼
若是是獲取文字,那麼把 nodes 中每一項的 textContent 存起來。
getText : function(){
var texts = [];
for(var i = 0; i < nodes.length;i++){
texts.push(nodes[i].textContent);
}
return texts;
}
複製代碼
若是是設置文字,經過遍歷,將要設置的文字依次賦值給 textContent 。
setText : function(text){
for(var i = 0; i < nodes.length;i++){
nodes[i].textContent = text;
}
return text;
}
複製代碼
測試運行:
var nodeTest = simpleTools('#item3');
nodeTest.setText('hello');
複製代碼
不管是設置仍是獲取,上面的代碼看起來是那麼相似,說明這就存在着優化的可能。咱們試圖將這兩個函數合併成爲一個,若是你有參數傳遞,那麼就說明你是須要設置文本,若是沒有參數傳入,那麼就說明你是想獲取文本。
text: function (text) {
if (text == undefined) {
var texts = [];
for (var i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent);
}
return texts;
}
else {
for (var i = 0; i < nodes.length; i++) {
nodes[i].textContent = text;
}
}
}
複製代碼
window.$ = function simpleTools(){...}
複製代碼
使用全局變量 $ 就至關於在用 simpleTools。
tips: 若是某變量是由 jQuery 構造出來的,在變量前加上一個 $
, 防止變量弄混。
eg:var $node = $(#item3)
第一種
window.$ = function simpleTools(nodeOrSelector) {
var nodes = {};
if (typeof nodeOrSelector === 'string') {
var temp = document.querySelectorAll(nodeOrSelector);
for (var i = 0; i < temp.length; i++) {
nodes[i] = temp[i];
}
nodes.length = temp.length;
} else if (nodeOrSelector instanceof Node) {
nodes = {
0 : nodeOrSelector,
length: 1
};
}
return {
addClass: function(classes) {
classes.forEach((value) =>{
for (var i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value);
}
});
},
text: function(text) {
if (text == undefined) {
var texts = [];
for (var i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent);
}
return texts;
} else {
for (var i = 0; i < nodes.length; i++) {
nodes[i].textContent = text;
}
}
}
};
};
複製代碼
第二種
window.$ = function simpleTools(nodeOrSelector) {
var nodes = {};
if (typeof nodeOrSelector === 'string') {
var temp = document.querySelectorAll(nodeOrSelector);
for (var 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) {
classes.forEach((value) =>{
for (var i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value);
}
});
};
nodes.text = function(text) {
if (text == undefined) {
var texts = [];
for (var i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent);
}
return texts;
} else {
for (var i = 0; i < nodes.length; i++) {
nodes[i].textContent = text;
}
}
};
return nodes;
};
複製代碼
你喜歡哪一種就挑哪一種啦
快動手試試寫個本身的 API 吧!