我们先思考一个问题:用DOM API 获取一个元素的兄弟姐妹元素应该怎么做?
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自己实现一个jQuery的API</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>
<script>
var allChildren = item3.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
}
}
console.log(array)
</script>
</body>
</html>
效果如图1:

接下来封装一下,所谓封装就是起个名字,写个函数:
function getSiblings(node) { /*这就是一个API*/
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
}
console.log(getSiblings(item3))
运行效果如图2:

好啦自己写的一个API已经可以正常使用了!
然后再写一个添加class的AP
封装一个函数:function addClass(node, classes){}
如果我们要给item3添加三个class,分别是a,b,c应该怎么做呢:
item3.classList.add('a')
item3.classList.add('b')
item3.classList.add('c')
效果如图3:

这代码也太丑了!有没有简洁的方法呢:
var classes = ['a','b','c']
classes.forEach((value)=> item3.classList.add(value))
能不能做到既能add又能remove呢?用哈希来做:
var classes = {'a':true,'b':false,'c':true}
for(let key in classes){
var value = classes[key]
if(value){
item3.classList.add(key)
}else{
item3.classList.remove(key)
}
}
效果如图4:

接下来封装一下:
function addClass(node,classes){
/* var classes = {'a':true,'b':false,'c':true} */
for(let key in classes){
var value = classes[key]
if(value){
node.classList.add(key)
}else{
node.classList.remove(key)
}
}
}
addClass(item3,{'a': true, 'b': false, 'c': true})
效果如图5:

完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自己实现一个jQuery的API</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>
<script>
function getSiblings(node) {
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
}
console.log( getSiblings(item3) )
function addClass(node,classes){
/* var classes = {'a':true,'b':false,'c':true} */
for(let key in classes){
var value = classes[key]
if(value){
node.classList.add(key)
}else{
node.classList.remove(key)
}
}
}
addClass(item3,{'a': true, 'b': false, 'c': true})
</script>
</body>
</html>
接下来把代码优化一下:
function addClass(node,classes){
/* var classes = {'a':true,'b':false,'c':true} */
for(let key in classes){
var value = classes[key]
var methodName = value ? 'add' : 'remove'
node.classList.add[methodName](key)
}
}
这两个API就写好了。 二、起个名字吧(命名空间)就叫jamDom
function getSiblings(node) {
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
}
function addClass(node,classes){
classes.forEach( (value)=> node.classList.add(value) )
}
window.jamDom = {}
jamDom.getSiblings = getSiblings
jamDom.addClass = addClass
jamDom.getSiblings(item3)
jamDOm.addClass(item3 , ['a','b','c'])
再优化一下:
window.jamDom = {}
jamDom.getSiblings = function (node) {
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
}
jamDom.addClass = function (node,classes){
classes.forEach( (value)=> node.classList.add(value) )
}
jamDom.getSiblings(item3)
jamDOm.addClass(item3 , ['a','b','c'])
如果我们想要用
item3.addClass( ['a','b','c'] )
这种形式,应该怎么做呢?
有两种方法,方法一:直接改node的原型
Node.prototype.getSiblings = function () {
var allChildren = this.parentNode.children
var 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.addClass(['a','b','c'])
//用call更加直观的了解
//item3.getSiblings.call(item3)
//item3.addClass.call(item3,['a','b','c'])
方法二,不要改Node原型
window.jQuery = function (node){
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.forEach( (value)=> node.classList.add(value) )
}
}
}
var node2 = jQuery(item3)
node2.getSiblings()
node2.addClass()