美文网首页
Javascript面向对象编程

Javascript面向对象编程

作者: 悄敲 | 来源:发表于2019-04-06 20:02 被阅读0次

    众所周知,面向对象编程具有以下3大特性:
    (1)封装性
    (2)继承性
    (3)多态性
    这里仅就以“封装性”来说明如何在JS里应用面向对象编程思想对比较通用的操作进行封装,以提高代码的重用性。


    tab例子

    先看下面向过程的写法:

    <!DOCTYPE html>
    <html>
    <head>
        <style>
            #tabBox input {
                background: #F6F3F3;
                border: 1px solid #FF0000;
            }
            #tabBox .active {
                background: #E9D4D4;
            }
            #tabBox div {
                width:300px; 
                height:250px; 
                display:none;
                padding: 10px;
                background: #E9D4D4;
                border: 1px solid #FF0000;
            }
        </style>
        <meta charset="utf-8" />
        <title>选项卡</title>
        <script>
            window.onload=function(){
                var tabBox = document.getElementById('tabBox');
                var tabBtns = tabBox.getElementsByTagName('button');
                var tabDivs = tabBox.getElementsByTagName('div');
                
                for(var i=0;i<tabBtns.length;i++){
                    tabBtns[i].index = i;
                    tabBtns[i].onclick = function (){
                        for(var j=0;j<tabBtns.length;j++){
                            tabBtns[j].className='';
                            tabDivs[j].style.display='none';
                        }
                        this.className='active';
                        tabDivs[this.index].style.display='block';
                    };
                }
            };
        </script>
    </head>
    <body>
      <div class="tab" id="tabBox">
        <button class="active">game</button>
        <button>travel</button>
        <button>music</button>
        <div>LOL</div>
        <div>Singapore</div>
        <div>ColdPlay</div>
    </div>
    </body>
    </html>
    

    下面一步步改成面向对象的形式。
    1.首先将嵌套的函数拿到window.onload外面,不能有函数嵌套,可以有全局变量。

     //将在嵌套函数里的变量提取到全局中
            var tabBtn = null;
            var tabDiv = null;
            
            window.onload = function(){
                var tabBox = document.getElementById('tabBox');
                tabBtns = tabBox.getElementsByTagName('button');
                tabDivs = tabBox.getElementsByTagName('div');
                
                for(var i=0;i<tabBtns.length;i++){
                    tabBtns[i].index = i;
                    //此处调用函数即可
                    tabBtns[i].onclick = clickBtn;
                }
            };
            
            //将嵌套函数提取到全局中
            function clickBtn(){
                for(var j=0;j<tabBtns.length;j++){
                    tabBtns[j].className='';
                    tabDivs[j].style.display='none';
                }
                this.className='active';
                tabDivs[this.index].style.display='block';
            };
    

    2.将全局的变量变为对象的属性,全局的函数变为对象的方法;将Tab的结构与事件绑定抽象成一个“类”Tab,将window.onload里的代码提取到一个构造函数里面,在window.onload里创建对象即可
    构造函数里只包含Tab对象实例的属性,即Tab的构成dom元素,并在其中进行相应事件的绑定;在原型对象上添加公用的方法。注意几处this的指向,要小心处理。

    // 构造函数
    function Tab(id) {
        const tabBox= document.getElementById(id);
        this.tabBtns=tabBox.getElementsByTagName('button');
        this.tabDivs=tabBox.getElementsByTagName('div');
        const _this=this;
        for(let i=0,len=this.tabBtns.length;i<len;i++){
            this.tabBtns[i].index=i;
            // this.tabBtns[i].addEventListener('click',this.btnClickHandler.bind(this,i),false);
            this.tabBtns[i].onclick=function () {
                // here 'this' points to this.tabBtns[i]
                _this.btnClickHandler(this);
            }
        }
    }
    Tab.prototype.btnClickHandler=function (btn) {
        //console.log(this);
        for(let j=0,l=this.tabBtns.length;j<l;j++){
            this.tabBtns[j].setAttribute('class','');
            this.tabDivs[j].style.display='none';
        }
        btn.setAttribute('class','active');
        this.tabDivs[btn.index].style.display='block';
    }
    

    3.可将抽象出来的Tab放到单独的js文件中,再引入,这样在html中就可简洁地使用Tab构造函数来构建需要的结构。

    <body>
    <div class="tab" id="tabBox1">
        <button class="active">game</button>
        <button>travel</button>
        <button>music</button>
        <div>LOL</div>
        <div>Singapore</div>
        <div>ColdPlay</div>
    </div>
    <br>
    <div class="tab" id="tabBox2">
        <button class="active">技术</button>
        <button>工具</button>
        <button>网站</button>
        <div>FE</div>
        <div>Vue</div>
        <div>https://www.w3school.com</div>
    </div>
    <script>
        window.onload=function(){
           let tab1=new Tab('tabBox1');
           let tab2=new Tab('tabBox2');
        }
    </script>
    </body>
    

    结果图


    两个Tab例子

    下面再补个拖动页面 div 元素的面向对象写法例子。这里关于 'this' 的处理更要注意。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>拖拽</title>
        <style>
            .box{
                width:100px;
                height:100px;
                background: #ff99cc;
                position: absolute;
            }
        </style>
    </head>
    <body>
    <div  class="box" id="box1">i'm a box1.</div>
    <div  class="box" id="box2">i'm a box2.</div>
    <script>
      window.onload=function () {
         let oBox1=new Drag('box1','#FF0000');
         let oBox2=new Drag('box2','#00FF00');
      }
    
      // 构造函数
      function Drag(id,color) {
          this.box=document.getElementById(id);
          this.box.style.backgroundColor=color;
          this.disX=0;
          this.disY=0;
          const self=this;
          this.box.onmousedown=function (e) {
               //console.log(this); // the 'box' div
              self.fnDown(e);
          }
      }
      Drag.prototype.fnDown=function (e) {
          let oEvent=e|| event;
          this.disX=oEvent.clientX-this.box.offsetLeft;
          this.disY=oEvent.clientY-this.box.offsetTop;
          let self=this;// 通过new Box 创建的实例
          document.onmousemove=function (e) {
              //console.log(this); // the document
              self.fnMove(e);
          }
          document.onmouseup=function (e) {
              self.fnUp(e);
          }
      }
    
      Drag.prototype.fnMove=function (e) {
          let oEvent=e|| event;
          this.box.style.left=oEvent.clientX-this.disX+'px';
          this.box.style.top=oEvent.clientY-this.disY+'px';
      }
    
      Drag.prototype.fnUp=function (e) {
          document.onmousemove=null;
          document.onmouseup=null;
      }
    </script>
    </body>
    </html>
    

    结果图


    两个可拖拽 div

    相关文章

      网友评论

          本文标题:Javascript面向对象编程

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