今天主要实现以下两个api:
- addClass:给指定标签增加class
- setText:给指定标签设置文本内容(textContent)
第一版
第一版用到命名空间,命名空间相当于给自己的库一个名字,当函数名称冲突,不会会覆盖掉之前的函数。
var ffyjq = {};
// 作用:获取传入的节点的兄弟节点
ffyjq.getSiblings = function (node){
// 取得传入的节点的父节点底下的所有子节点,包括传入的节点
let itemList = node.parentNode.children;
// array用于存放结果
var array = {length:0};
// 遍历所有子节点
for(var i = 0;i<itemList.length;i++){
// 判断子遍历的节点是否就是传入的节点,需求要求的是获取兄弟节点,所以要把传入的节点排除,其他节点放入array
if(itemList[i] !== node){
array[array.length] = itemList[i];
array.length ++ ;
}
}
// 返回array
return array;
}
ffyjq.addClass =
function (node,classes){
for(var k in classes){
var methodName = classes[k]?"add":"remove";
node.classList[methodName](k);
}
}
ffyjq.setText = function(node,text){
node.textContent = text;
};
var classes = {class1:true,class2:false,class3:true};
ffyjq.addClass(item3,classes);
ffyjq.setText(item3,"aaa");
console.log(ffyjq.getSiblings(item3));
第二版
第一版的缺点是只能去调用ffyjq.addClass(item3,classes),而jq的调用方式是item3.addClass(classes)。想要实现jq的调用方式,有以下两种方法:
- 扩展 Node 接口,直接在 Node.prototype 上加函数:
//核心代码不变,只是给Node.prototype增加方法
Node.prototype.getSiblings = function (){
let itemList = this.parentNode.children;
var array = {length:0};
for(var i = 0;i<itemList.length;i++){
if(itemList[i] !== this){
array[array.length] = itemList[i];
array.length ++ ;
}
}
return array;
}
Node.prototype.addClass = function (classes){
for(var k in classes){
var methodName = classes[k]?"add":"remove";
this.classList[methodName](k);
}
}
Node.prototype.setText= function(node,text){
node.textContent = text;
};
console.log(item3.getSiblings.call(item3));
item3.addClass.call(item3,{class1:true,class2:false,class3:true});
这种方法的缺点是容易命名重复,并且修改原型本身就不合适。
- 给节点加上接口,并且返回接口:
window.jQuery = function(nodeOrSelector){
var nodes;
//传入的是字符串,就根据传入字符串查询节点
if(typeof nodeOrSelector === 'string'){
nodes = document.querySelectorAll(nodeOrSelector);
//传入的是节点,就把节点放入伪数组
}else if(nodeOrSelector instanceof Node){
nodes = {
0:nodeOrSelector,
length:1
};
}
//给节点加上getSiblings 接口
nodes.getSiblings = function(){
};
//给节点加上addClass 接口
nodes.addClass = function(classes){
for(var i = 0;i<nodes.length;i++){
for(var k in classes){
var methodName = classes[k]?"add":"remove";
nodes[i].classList[methodName](k);
}
}
};
//给节点加上setText 接口
nodes.setText = function(text){
for(var i = 0;i<nodes.length;i++){
nodes[i].textContent = text;
}
};
return nodes;
};
//给个jQuery加缩写
window.$ = jQuery;
var node = $("ul>li");
node.addClass({blue:true});
node.setText("hi");