自己实现jQuery API
2018-10-16 本文已影响0人
阿龙哟
this 是call 的第一个参数!!!
this是call的第一个参数!!!
this是call的第一个参数!!!
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="封装两个函数" />
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body >
<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>
</body>
</html>
封裝兩個函數:1.獲取相鄰元素,給偽數組添加元素
1.0版,虽然可以实现,但是在全局中定义这些函数可能会覆盖别人定义的函数
//获取所有相邻元素
function getSiblings(node) {
var allChildren = node.parentNode.children
var siblings = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i].id !== node.id) {
siblings[siblings.length] = allChildren[i] //给伪数组添加元素
siblings.length += 1
}
}
return siblings
}
var classes = {
a: true,
b: false,
c: true
}
//添加类名
function addClass(classes,node) {
for (let key in classes) {
if (classes[key]) {
node.classList.add(key)
} else {
node.classList.remove(key)
}
}
}
addClass.call(undefined,classes,item1)
2.0版
//获取所有相邻元素
function getSiblings(node) {
var allChildren = node.parentNode.children
var siblings = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i].id !== node.id) {
siblings[siblings.length] = allChildren[i] //给伪数组添加元素
siblings.length += 1
}
}
return siblings
}
//添加类名
function addClass(classes,node) {
//代码优化准则,只要有相似代码,就一定可以优化
for (let key in classes) {
var value = classes[key]
var method = value ? 'add':'remove'
node.classList[method](key)
}
}
window.along = {}
along.getSiblings=getSiblings
along.addClass = addClass
console.log(along.getSiblings(item1))
along.addClass({'a':true,'c':false},item1)
//设计模式 命名空间
定义一个名为along的对象空间,其中有两条函数属性,分别对应着这两个函数,使用的时候调用along里的函数,就可以避免覆盖别人函数的问题了,这种方法是一种设计模式名为命名空间
但是还是会有点问题,每次使用都要前缀名
3.0版
能不能直接用item来调用这两个办法,所以想到在原型上添加这两个方法
//获取所有相邻元素
Node.prototype.getSiblings=function () {
var allChildren = this.parentNode.children
var siblings = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i].id !== this.id) {
siblings[siblings.length] = allChildren[i] //给伪数组添加元素
siblings.length += 1
}
}
return siblings
}
//添加类名
Node.prototype.addClass=function(classes) {
classes.forEach((value)=>this.classList.add(value))
}
console.log(item2.getSiblings())
item4.addClass(['a','b'])
4.0 版直接在原型上添加好像也有点问题,要是这个函数原来原型上就有了怎么办?所以从新构建一个Node2对象,,上面那种方法是通过this获取节点,这里我们直接传入一个node节点
window.Node2 = function(node) {
return {
getSiblings: function() {
var allChildren = node.parentNode.children
var siblings = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i].id !== node.id) {
siblings[siblings.length] = allChildren[i] //给伪数组添加元素
siblings.length += 1
}
}
return siblings
},
addClass: function(classes) {
classes.forEach((value) => node.classList.add(value))
}
}
}
var node2 = Node2(item3)
console.log(node2.getSiblings(item2))
node2.addClass(['a','b'])
同时,把Node2改成jQuery,这个就是jQuery的模式了。给我旧的对象返回一个新的API,有新的方法
5.0版 改进传入的参数,如果是Node节点,就直接使用,如果是个选择器,则找到相对应的节点
window.jQuery = function(nodeOrSelector) {
let node
if(typeof nodeOrSelector === 'string'){
node=document.querySelector(nodeOrSelector)
}
else{
node = nodeOrSelector
}
return {
getSiblings: function() {
var allChildren = node.parentNode.children
var siblings = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i].id !== node.id) {
siblings[siblings.length] = allChildren[i] //给伪数组添加元素
siblings.length += 1
}
}
return siblings
},
addClass: function(classes) {
classes.forEach((value) => node.classList.add(value))
}
}
}
var node2 = jQuery('ul>li:nth-child(5)')
console.log(node2.getSiblings())
node2.addClass(['blue','a','b'])
升级版JQuery函数
window.jQuery = function(orderSelector) {
let nodes = {}
if (typeof orderSelector === 'string') {
let temp = document.querySelectorAll(orderSelector)
for (let i = 0; i < temp.length; i++) {
nodes[i] = temp[i]
nodes.length = temp.length
}
} else if (oederSelector instanceof Node) {
nodes = {
0: orderSelector,
length: 1
}
}
nodes.addClass = function(classes) {
classes.forEach((value) => {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value)
}
})
}
nodes.text = function(text) {
if (text === undefined) {
let 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
}
var node2 = jQuery('ul>li')
node2.addClass(['red', 'blue'])
console.log(node2.text())
node2.text('tuesday')
模拟jQuery,实现了选择器,实现了添加类名,读取文本设置文本这几个
函数
再加个缩写
window.$ = jQuery
var node2 = $('ul>li')
Query 优点:
1.兼容性很好
2除了 DOM操作,还有动画,ajax
3.jQuery 的功能更丰富