封装js过程

作者: H_uan | 来源:发表于2018-09-17 17:53 被阅读92次

    主要记录通过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
    ② 所有声明的对象都不相等,因为地址不相同

    打印结果为:


    除自己外的兄弟元素.png
    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});
    
    结果: 添加class.png

    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封装方法

    相关文章

      网友评论

        本文标题:封装js过程

        本文链接:https://www.haomeiwen.com/subject/tikvgftx.html