JS対象向けプログラミング実現のTabタブケース詳細


本論文の例は、JSがオブジェクトに向けてプログラミングされたTabタブについて述べる。皆さんに参考にしてあげます。具体的には以下の通りです。
タブの例

以下はプロセスに簡単に向かう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 tabBtn = tabBox.getElementsByTagName('input');
      var tabDiv = tabBox.getElementsByTagName('div');
      
      for(var i=0;i<tabBtn.length;i++){
        tabBtn[i].index = i;
        tabBtn[i].onclick = function (){
          for(var j=0;j<tabBtn.length;j++){
            tabBtn[j].className='';
            tabDiv[j].style.display='none';
          }
          this.className='active';
          tabDiv[this.index].style.display='block';
        };
      }
    };
  </script>
</head>
 
<body>
  <div id="tabBox">
    <input type="button" value="  " class="active" />
    <input type="button" value="  " />
    <input type="button" value="  " />
    <div style="display:block;">      </div>
    <div>      </div>
    <div>      </div>
  </div>
</body>
</html>
以下は徐々に対象に向かう形に変えます。
1.まずネストされた関数をwindow.onloadの外に持ち出します。関数がネストされていないので、グローバル変数があります。すべての書き換えは最終的な効果は変わらない。

<script>
    //                
    var tabBtn = null;
    var tabDiv = null;
    
    window.onload = function(){
      var tabBox = document.getElementById('tabBox');
      tabBtn = tabBox.getElementsByTagName('input');
      tabDiv = tabBox.getElementsByTagName('div');
      
      for(var i=0;i<tabBtn.length;i++){
        tabBtn[i].index = i;
        //        
        tabBtn[i].onclick = clickBtn;
      }
    };
    
    //           
    function clickBtn(){
      for(var j=0;j<tabBtn.length;j++){
        tabBtn[j].className='';
        tabDiv[j].style.display='none';
      }
      this.className='active';
      tabDiv[this.index].style.display='block';
    };
    
  </script>
2.グローバルの変数をオブジェクトの属性にし、大域の関数をオブジェクトにする方法。window.onloadのコードをコンストラクションの中に抽出して、window.onloadの中でオブジェクトを作成すればいいです。下記のコードは実行に問題があります)。
ここで注意しなければならないのは、構造関数Tabにおけるthisは、以前のthisとは異なる(ここではnewによってオブジェクトを作成する)。上記の例では、thisは使用者を指します。コンストラクタでは、thisはvar tab=new Tab()、つまりtabというオブジェクトを指しています。
このコードの問題を言います。Tabの原型にclickBtn方法を追加した後、clickBtn方法のthisはvar tab=new Tabを指すべきですが、this.tabBtn[i].onclick=this.clickBtn;clickBtnをthis.tabBtn[i]に追加しました。つまりinputボタンです。clickBtnの所属はTabオブジェクトからinputボタンになりました。
clickBtnの所属がinputボタンになったら、clickBtnの中のthisの指向ボタンは、clickBtnのコードを見てください。this.tabBtn、this.tabDiv、inputボタンにはこの二つの属性がありますか?ありません。だから間違います。
   

<script>   
    window.onload = function(){
      var tab = new Tab("tabBox");
    }
  
    /**
     *    window.onload             
     * [     Tab         Tab ]
     * @param {Object} id:   id        
     */
    function Tab(id){
      var tabBox = document.getElementById(id);
      //               
      this.tabBtn = tabBox.getElementsByTagName('input');
      this.tabDiv = tabBox.getElementsByTagName('div');
      
      for(var i=0;i<this.tabBtn.length;i++){
        this.tabBtn[i].index = i;
        
        //          ,   clickBtn     this.tabBtn[i]
        this.tabBtn[i].onclick = this.clickBtn;
      }
    };
    //                   ,         
    Tab.prototype.clickBtn = function(){
      alert(this); //HTMLInputElement
      for(var j=0;j<this.tabBtn.length;j++){
        this.tabBtn[j].className='';
        this.tabDiv[j].style.display='none';
      }
      this.className='active';
      this.tabDiv[this.index].style.display='block';
    }; 
  </script>
3.clickBtnの呼び出しを一つの関数に置くと、clickBtnの所属は変わりません。alert(this)この時ポップアップしたのはObjectで、clickBtnの所属関係は変わっていませんか?それともTabオブジェクトですか?しかし、もう一つの問題があります。この時clickBtnの中のthisはtabオブジェクトを指します。this.className、this.index、ここのthisはtabオブジェクトを指しますが、対象の中にこの二つの属性がありますか?いいえ、また間違えます。ですから、第4ステップは改造を続けます。

window.onload = function(){
      var tab = new Tab("tabBox");
    }
  
    /**
     *    
     * @param {Object} id:   id
     */
    function Tab(id){
      var tabBox = document.getElementById(id);
      
      this.tabBtn = tabBox.getElementsByTagName('input');
      this.tabDiv = tabBox.getElementsByTagName('div');
      
      for(var i=0;i<this.tabBtn.length;i++){
        this.tabBtn[i].index = i;
        // this       ,                 
        var _this = this;
        //          ,     clickBtn       
        this.tabBtn[i].onclick = function(){
          //          this,this  this.tabBtn[i]
          _this.clickBtn();
        };
      }
    };
    //       
    Tab.prototype.clickBtn = function(){
      alert(this); //Object
      for(var j=0;j<this.tabBtn.length;j++){
        this.tabBtn[j].className='';
        this.tabDiv[j].style.display='none';
      }
      this.className='active';
      this.tabDiv[this.index].style.display='block';
    };
4.クリックボタンをパラメータの形でclickBtnに伝えます。

window.onload = function(){
      var tab = new Tab("tabBox");
    }
  
    /**
     *    
     * @param {Object} id:   id
     */
    function Tab(id){
      var tabBox = document.getElementById(id);
      
      this.tabBtn = tabBox.getElementsByTagName('input');
      this.tabDiv = tabBox.getElementsByTagName('div');
      
      for(var i=0;i<this.tabBtn.length;i++){
        this.tabBtn[i].index = i;
        var _this = this;
        this.tabBtn[i].onclick = function(){
          //    this    this.tabBtn[i], input  
          _this.clickBtn(this);
        };
      }
    };
    //              
    Tab.prototype.clickBtn = function(btn){
      for(var j=0;j<this.tabBtn.length;j++){
        this.tabBtn[j].className='';
        this.tabDiv[j].style.display='none';
      }
      btn.className='active';
      this.tabDiv[btn.index].style.display='block';
    };
5.最終版――コードを個別のjsファイルに抽出し、使う時に導入すればいいです。一般的にオブジェクト指向のプログラムを書くには時間がかかります。
Tab.js

/**
 *    
 * @param {Object} id    id
 */
function Tab(id){
  var tabBox = document.getElementById(id);
  this.tabBtn = tabBox.getElementsByTagName('input');
  this.tabDiv = tabBox.getElementsByTagName('div');
  
  for(var i=0;i<this.tabBtn.length;i++){
    this.tabBtn[i].index = i;
    var _this = this;
    this.tabBtn[i].onclick = function(){
      _this.clickBtn(this);
    };
  }
};
/**
 *  Tab           
 * @param {Object} btn      
 */
Tab.prototype.clickBtn = function(btn){
  for(var j=0;j<this.tabBtn.length;j++){
    this.tabBtn[j].className='';
    this.tabDiv[j].style.display='none';
  }
  btn.className='active';
  this.tabDiv[btn.index].style.display='block';
};
使用:tab.は使用する時が見えます。簡単に二つのタブを作成できます。

<!DOCTYPE html>
<html>
<head>
  <style>
    .tab input {
      background: #F6F3F3;
      border: 1px solid #FF0000;
    }
    .tab .active {
      background: #E9D4D4;
    }
    .tab div {
      width:300px; 
      height:250px; 
      display:none;
      padding: 10px;
      background: #E9D4D4;
      border: 1px solid #FF0000;
    }
  </style>
  <meta charset="utf-8" />
  <title>   </title>
  <!--   tab.js -->
  <script type="text/javascript" src="../js/tab.js" ></script>
  <script>  
    window.onload = function(){
      var tab1 = new Tab("tabBox1");     
      var tab2 = new Tab("tabBox2");
    }  
  </script>
</head>
 
<body>
  <div class="tab" id="tabBox1">
    <input type="button" value="  " class="active" />
    <input type="button" value="  " />
    <input type="button" value="  " />
    <div style="display:block;">      </div>
    <div>      </div>
    <div>      </div>
  </div>
  <br />
  <div class="tab" id="tabBox2">
    <input type="button" value="  " class="active" />
    <input type="button" value="  " />
    <input type="button" value="  " />
    <div style="display:block;">Js、Vue</div>
    <div>VSCode</div>
    <div>CSDN</div>
  </div>
</body>
</html>

また、JSの対象に向けたthisを簡単にまとめてみます。thisは普通、二つの場合に問題が発生します。一つはタイマーを使って、二つは事件です。上記の例からも分かります。次の表現に注意してください。構造関数の中です。他の場合、thisは使用者を指します。
名前が表示されていない効果が見られますが、ここに来た理由は明らかです。14行目のコードの中でthis.nameです。ここのthisは誰を指していますか?windowを指しています。setIntervalはwindowに属しています。

<!DOCTYPE html>
<html>
  <meta charset="UTF-8" />
  <head>
    <script>
      
      function Person(name){
        this.name = name;
        //   
        setInterval(this.showName, 3000);
      }
      Person.prototype.showName = function(){
        alert(this); //window
        alert("  :"+this.name);
      }
      
      var p1 = new Person("jiangzhou");
      
    </script>
  </head>
</html>
 解決方法:上記の例では、実行するコードを一つのfunctionで包んで、所属関係を変化させないようにします。functionでメソッドを呼び出す時に使うのは外部変数'_'であることに注意してください。this事件の処理は上の例で説明しました。

function Person(name){
   this.name = name;
   var _this = this;
   setInterval(function(){
      this.showName();
   }, 3000);
}
Person.prototype.showName = function(){
   alert(this); //[Object Object]
   alert("  :"+this.name); //  :jianghzou
}      
var p1 = new Person("jiangzhou");
関心のある友達はオンラインHTML/CSS/JavaScriptコードを使ってツールを実行できます。http://tools.jb51.net/code/HtmlJsRunは上記のコードの運行効果をテストします。
JavaScriptに関する詳細な内容について興味がある読者は、このサイトのテーマを見ることができます。「javascript対象向け入門教程」「JavaScriptエラーとデバッグテクニックのまとめ」「JavaScriptデータ構造とアルゴリズム技術のまとめ」「JavaScriptはアルゴリズムと技術の総括を遍歴します。」「JavaScript数学演算の使い方のまとめ
本論文で述べたように、JavaScriptプログラムの設計に役に立ちます。