<ul>
<li id="item1">選項1</li>
<li id="item2">選項2</li>
<li id="item3">選項3</li>
<li id="item4">選項4</li>
<li id="item5">選項5</li>
</ul>
let allChildren = item3.parentNode.children
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== item3) {
array[array.length] = allChildren[i] //給僞數組添加子元素
array.length += 1
}
}
console.log(array) // 獲得items3的兄弟元素的僞數組
複製代碼
function getSiblings(node) { // 這個這就是API
let allChildren = node.parentNode.children
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
console.log(getSiblings(item3)) // 獲得items3的兄弟元素
複製代碼
let classes = {'a':true,'b':false,'c':true}
for (let key in classes) { // 遍歷這個哈希表
let value = classes[key]
if (value) { // value值爲真則添加,假則刪除
node.classList.add(key)
} else {
node.classList.remove(key)
}
}
複製代碼
function addClass(node, classes) {
for (let key in classes) {
let value = classes[key]
if (value) {
node.classList.add(key)
} else {
node.classList.remove(key)
}
}
}
addClass(item3, {a:true,b:false,c:true})
複製代碼
只要有類似的代碼,就有優化的空間 。css
function addClass(node, classes) {
for (let key in classes) {
let value = classes[key]
let methodName = value ? 'add':'remove' //若是value值爲真,methodName爲add,假則爲remove
node.classList.['methodName'](key)
}
}
ffdom.addClass(item3, {a:true,b:false,c:true})
複製代碼
function addClass(node, classes) {
classes.forEach((value)=> node.classList.add(value))
}
addClass(item3, ['a','b','c'])
複製代碼
利用命名空間的設計模式,關聯兩個獨立的函數,這樣還能夠防止代碼覆蓋的問題。node
window.xxxxdom = {} /*yui使用的就是命名空間的模式*/
xxxxdom.getSiblings = function(node) {
let allChildren = node.parentNode.children
let array = { // 僞數組
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i] // 僞數組沒有push()方法,利用length來添加元素
array.length += 1
}
}
return array
}
xxxxdom.addClass = function(node, classes) {
classes.forEach((value)=> node.classList.add(value))
}
xxxxdom .getSiblings(items)
xxxxdom .addClass(item3, ['a','b','c'])
複製代碼
去掉xxxxdom,改寫成如下模式,咱們有兩種方法。設計模式
item3.getSiblings()
item3.addClass(['a','b','c'])
複製代碼
這樣作的缺點:會產生代碼覆蓋的問題。api
Node.prototype.getSiblings = function() {
let allChildren = this.parentNode.children // this 隱式指向 Node
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== this) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
Node.prototype.addClass = function(classes) {
classes.forEach((value)=> this.classList.add(value))
}
console.log(item3.getSiblings()) // 獲得一個item3的兄弟元素的僞數組
item3.addClass(['a','b','c'])
複製代碼
用call就是顯示指定this,this是第一個參數 不用是顯示隱式指定this數組
item3.getSiblings.call(item3)
item3.addClass.call(item3,['a','b','c'])
複製代碼
本身創造一個構造函數,就是能夠解決代碼覆蓋的問題。bash
創造一個Node2的構造函數,它接收一個node參數,返回一個哈希表,它的key就是咱們的想要的api。使用時,傳入node參數,就可使用了。dom
window.Node2 = function(node) {
return {
getSiblings: function() {
let allChildren = node.parentNode.children // node 是傳進來的節點參數
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
addClass: function(classes) {
classes.forEach((value)=> node.classList.add(value))
}
}
}
var node2 = Node2(item3)
node2.getSiblings()
node2.addClass(['a','b','c']))
複製代碼
將Node2改成jQuery,jQuery接收一箇舊的dom,返回一個新的對象,這個新的對象有新的api,內部實現仍是調用舊的api,只不過好用了一些。jQuery實質上是一個構造函數,接收一個參數,這個參數可使節點或選擇器,而後返回一個方法對象去操做節點。函數
window.jQuery = function(node) {
return {
getSiblings: function() {
let allChildren = node.parentNode.children
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
addClass: function(classes) {
classes.forEach((value)=> node.classList.add(value))
}
}
}
var node2 = jQuery(item3)
node2.getSiblings()
node2.addClass(['a','b','c']))
複製代碼
傳參node能夠不僅是node還能夠是選擇器selector,只須要進行類型檢測便可。優化
window.jQuery = function(nodeOrSelector) {
let node
if(typeof nodeOrSelector === 'string') { // 類型檢測
node = document.querySelector(nodeOrSelector)
} else {
node = nodeOrSelector
}
return {
getSiblings: function() {
let allChildren = node.parentNode.children
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
addClass: function(classes) {
classes.forEach((value)=> node.classList.add(value))
}
}
}
var node2 = jQuery('#item3') // 能夠經過選擇器來找到node了
node2.getSiblings()
node2.addClass(['red','b','c']))
相關css
css
.red {color: red;}
複製代碼
window.jQuery = function(nodeOrSelector) {
let nodes
if(typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector) // 僞數組
for(let i=0;i<temp.length;i++) {
node[i] = temp[i]
}
nodes.length = temp.length // 利用temp去掉多餘的原型,直接指向object.prototype
} else if(nodeOrSelector instanceof Node) {
nodes = {0:nodeOrSelector, length:1}
}
nodes.getSiblings = function() {}
nodes.addClass = function() {}
return nodes
}
var node2 = jQuery('ul > li')
console.log(node2)
複製代碼
window.jQuery = function(nodeOrSelector) {
let nodes
if(typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector) // 僞數組
for(let i=0;i<temp.length;i++) {
node[i] = temp[i]
}
nodes.length = temp.length object.prototype
} else if(nodeOrSelector instanceof Node) {
nodes = {0:nodeOrSelector, length:1}
}
nodes.addClass = function() { //添加addClass()方法
classes.forEach((value)=> {
for(let i = 0; i < nodes.length; i++) {
node[i].classList.add(value)
}
}
}
return nodes
}
var node2 = jQuery('ul > li')
node2.addClass(['blue'])
複製代碼
添加getText()和setText()動畫
window.jQuery = function(nodeOrSelector) {
let nodes
if(typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector) // 僞數組
for(let i=0;i<temp.length;i++) {
node[i] = temp[i]
}
nodes.length = temp.length // 利用temp去掉多餘的原型,直接指向object.prototype
} else if(nodeOrSelector instanceof Node) {
nodes = {0:nodeOrSelector, length:1}
}
nodes.addClass = function() {
classes.forEach((value)=> {
for(let i = 0; i < nodes.length; i++) {
node[i].classList.add(value)
}
}
}
nodes.getText = function() { // 添加getText()
var texts = []
for(let i = 0; i < nodes.length; i++) {
text.push(nodes[i].textContent)
}
return texts
}
nodes.setText = function() { // 添加setText()
for(let i = 0; i < nodes.length: i++) {
nodes[i].textContent = texgt
}
}
return nodes
}
var node2 = jQuery('ul > li')
node2.addClass(['blue'])
node2.getText()
node2.setText('hi')
複製代碼
window.jQuery = function(nodeOrSelector) {
let nodes = {}
if(typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector) // 僞數組
for(let i=0;i<temp.length;i++) {
node[i] = temp[i]
}
nodes.length = temp.length // 利用temp去掉多餘的原型,直接指向object.prototype
} else if(nodeOrSelector instanceof Node) {
nodes = {0:nodeOrSelector, length:1}
}
nodes.addClass = function() {
classes.forEach((value)=> {
for(let i = 0; i < nodes.length; i++) {
node[i].classList.add(value)
}
}
}
node2.text = function(text) { // 將getText()和setText()合併
if(text === undefined) {
var texts = []
for(let i = 0; i < nodes.length; i++) {
text.push(nodes[i].textContent)
}
return texts
}
} else {
for(let i = 0; i < nodes.length: i++) {
nodes[i].textContent = text
}
}
return nodes
}
var node2 = jQuery('ul > li')
node2.addClass(['blue'])
console.log(node2.text())
node2.text('hi')
複製代碼
jQuery的實現思路:建立一個jQuery構造函數,接收一個node或selector,並把它封裝成一個僞數組,而後在這個僞數組上增長几個api,返回這個僞數組。
window.jQuery = function(nodeOrSelector) {
let nodes = {
0: nodeOrSelector,
length: 1
}
nodes.addClass = function(classes) {}
nodes.text = function(text) {}
return nodes
}
var node2 = jQuery('ul > li')
{0: li, 1: li, length: 5, addClass: f, text: f}
node2.addClass(['blue'])
node2.text()
node2[0].classList.add('blue')
複製代碼
jQuery的優勢:
飢人谷jQeury相關課程https://xiedaimala.com/