主要记录通过js封装一个jquery的addClass方法的过程
https://www.cnblogs.com/baiyunke/p/7821299.html
html代码:
<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>
1、传统封装函数
js封装一个获取除自己外的兄弟元素
代码片段:
function getSibling(node){
var allChildren= node.parentNode.children;
var array={length:0}
for(var i= 0;i<allChildren.length;i++){
if(allChildren[i] !== node){
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
console.log( getSibling(item3)) //传入item3
注意:只用!== 或 ===, 不要用 ==或!=
具体看文章https://zhuanlan.zhihu.com/p/22745278
结论是:
① NaN !== NaN
② 所有声明的对象都不相等,因为地址不相同
打印结果为:
js封装一个添加Class的函数
function addClass(node,classes) {
for(var key in classes){
var value = classes[key];
// if(value){
// node.classList.add(key);
// }else{
// node.classList.remove(key);
// }
// 可替换为:
var methodName= value?'add':'remove'
node.classList[methodName](key);
}
}
addClass(item3,{'red':true,'blue':false});
结果:2、命名空间
var dom = {}
dom.getSiblings(node)
dom.addClass(node, {a: true, b: false})
window.wh = {}//一个名叫wh的库
wh.getSibling = getSiblings
wh.addClass = addClass
wh.getSibling(item3)//调用getSibling方法
wh.addClass(item3,{'red':true,'blue':false})//调用addClass方法
命名空间的好处:1、有一个库的名字 2、避免全局变量覆盖
上述代码可变为:
window.wh = {}
wh.getSibling = function (a) {
var allitem = a.parentNode.children;
var array = {length:0};
for(var i=0;i<allitem.length;i++){
if(allitem[i] !== a ){
array[array.length] = allitem[i]
array.length += 1;
}
}
return array;
}
wh.addClass = function (node,classes){
classes.forEach((value) => node.classList.add(value));
// classes.forEach(function (item) {
// node.classList.add(item)
// })
}
wh.addClass(item2,['red','blue']);
命名空间的缺点:每次都要调一次库
3、变形
换一种调用方式:
node.getSiblings()
node.addClass()
-
方法一:扩展 Node 接口
直接在 Node.prototype 上加函数
小例子:
Node.prototype.getSiblings = function(){
return 1
}
console.log(item3.getSibling());//1
console.dir(item3)//原型中有getSiblings()方法
即可以用
item3.getSibling()直接获取函数
上述例子可变形为:
Node.prototype.getSibling = function () {
var allChildren = this.parentNode.children; //this即调用函数的item3
var array = {length:0}
for(var i = 0;i<allChildren.length;i++){
if(allChildren[i] !== this){
array[array.length] = allChildren[i];
array.length += 1;
}
}
return array
}
console.log(item3.getSibling());//除item3的所有item
//等价:console.log(item3.getSibling.call(item3));//call的第一个参数即this
Node.prototype.addClass = function (classes) {
classes.forEach( (item) => this.classList.add(item) )
}
item3.addClass(['red']);//id为item3的li标签字体颜色变红
//等价: item3.addClass.call(item3,['red']);
强调:this是call的第一个参数
-
方法二:新的接口 BetterNode
上述例子可变形为:
window.Node2 = function (node) {
return{
getSibling:function () {
var allChildren = node.parentNode.children;
var array = {length:0}
for(var 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((className) => {node.classList.add(className)})
}
}
}
var node2 = Node2(item3);
console.log(node2.getSibling());//除item3的所有li
node2.addClass(['red']);//item3字体变红
改进:
接收多个node
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){
node = {0:nodeOrSelector,length:0}
}
nodes.getSiblings = function () {}
nodes.addClass = function (classes) {
classes.forEach((value) => {
for(let i= 0;i<nodes.length;i++){
nodes[i].classList.add(value)
}
})
}
//获取文本
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(var i = 0;i<nodes.length;i++){
nodes[i].textContent = text
}
}
//合并方法 获取或者设置文本
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(var i = 0;i<nodes.length;i++){
nodes[i].textContent = text
}
}
}
return nodes;
}
var node2 = jQuery('ul>li');
node2.addClass(['red']);//调用DOM api
console.log(node2.getText());// [ "选项1", "选项2", "选项3", "选项4", "选项5" ]
node2.setText('hello');
node2.text('hi');
console.log( node2);//0:li 1:li ... addClass:f ...
console.log(node2[0]);//第一个li
//nodes;//闭包 操作一个访问不到的变量
//jQuery是一个函数
//node2是函数的返回值
完成了一个简单的js封装方法