封装函数
用原生DOM和js模仿jQuery的功能。
1.0版本
不能输入选择器字符串。只能输入单个node,操作单个元素。
//得到兄弟标签元素(处于同一级的所有元素)
function getSiblings(node) {
var allChildren = node.parentNode.children
var array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== item3) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
//给标签添加class
function addClass(node, classes) {
for (let key in classes) {
var value = classes[key]
var methodName = value ? 'add' : 'remove'
node.classList[methodName](key)
}
}
2.0版本
输入选择器字符串和node。只能操作单个元素。
function (nodeOrSelector) {
//前面加入类型检测
if (typeof nodeOrSelector === 'string') {
node = document.querySelector(nodeOrSelector) //伪数组
} else {
node = nodeOrSelector
}
return {
getSiblings: function () {
var allChildren = node.parentNode.children
var 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) {
for (let key in classes) {
var value = classes[key]
var methodName = value ? 'add' : 'remove'
node.classList[methodName](key)
}
},
addText: function (text) {
node.textContent = text
}
}
}
3.0版本
可以输入node和选择器字符串,可以操作多个node。
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.getText = function () {
var texts = []
for (let i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent)
}
return texts
}
nodes.setText = function (text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
//合并get和set
nodes.text = function (text) {
if (text === undefined) {
var texts = []
for (let i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent)
}
return texts
} else {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
return nodes
}
nodes.addClass = function (classes) {
for (let i = 0; i < nodes.length; i++) {
for (let key in classes) {
var value = classes[key]
var methodName = value ? 'add' : 'remove'
nodes[i].classList[methodName](key)
}
}
}
return nodes
}
命名空间
命名空间的优点
- 有识别性
- 和其他变量分开,不会影响全局变量
方法一
window.leidom = {}
leidom.getSiblings = getSiblings
leidom.addClass = addClass
leidom.getSiblings(item3)
leidom.addClass(item1, {
'red': true
})
方法二:Node.prototype来实现
Node.prototype.getSiblings = function(){···}
Node.prototype.addClass = function(){···}
//function参数用this代替
item1.getSiblings()
item3.addClass({ 'cui': true })
//等于
item1.getSiblings.call(item1)
item3.addClass.call(item3, {
'cui': true
})
方法三:新的接口
jQuery是一个构造函数,函数执行后返回nodes对象,nodes对象里包含操作nodes对象的函数。
window.$ = window.jQuery
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.getText = function () {
var texts = []
for (let i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent)
}
return texts
}
nodes.setText = function (text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
//合并get和set
nodes.text = function (text) {
if (text === undefined) {
var texts = []
for (let i = 0; i < nodes.length; i++) {
texts.push(nodes[i].textContent)
}
return texts
} else {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
return nodes
}
nodes.addClass = function (classes) {
for (let i = 0; i < nodes.length; i++) {
for (let key in classes) {
var value = classes[key]
var methodName = value ? 'add' : 'remove'
nodes[i].classList[methodName](key)
}
}
}
return nodes
}
$('li').addClass({'blue':true,'red':true})
$(item5).text('lei')
$('li').text()
jQuery 在兼容性方面做得很好,1.7 版本兼容到 IE 6
jQuery 还有动画、AJAX 等模块,不止 DOM 操作
jQuery 的功能更丰富
jQuery 使用了 prototype,我们没有使用