HTML DOM 的 JavaScript 類別實作方法


基本上,在 JavaScript 裡應該是沒有所謂的類別(class)的。以 Heresy 來看,這樣要把 JavaScript 寫的模組化的話,似乎有點麻煩…不過,所幸在 JavaScript,所有的 function 都可以當作物件來使用,而也此,實際上 JavaScript 還是可以透過它強大的 function 的功能,做到類似 class 的物件導向的寫法的!

寫法呢?大致上就是:

function ClassA( var1 )
{
    this.memberData1 = var1; // 當作 ClassA 的 member data
 
    // 當作 ClassA 的 member function
    this.memberFunction1 = function( var2 ){ 
        alert( this.memberData1 + var2 );
    };
}

在這樣寫後,基本上就可以把 ClassA 當作一個 class 來用了~可以直接寫:

var obj1 = new ClassA( 0 );
obj1.memberFunction1( 10 );

這樣,就會出現顯示「10」的對話框了~而就算同時有兩個由 ClassA 產生的物件,彼此也不會互相影響到。這樣的寫法,算是相當方便的!

而在把 JavaScript 的程式物件化後,接下來呢?Heresy 想做的,就是繼續把 HTML DOM 的程式,也物件化了~也就是,把一個複雜的 HTML 介面,從產生到按下去後會觸發的動作,都把它給物件化,以增加重複使用率!

Heresy 的寫法滿簡單的,大致上,就是寫成:

function UI_01()
{
  // 產生介面的 function
  this.createUI = function( widgetID ){
 
    // 取得 root element,作為產生 element 的根元件
    var wRoot = document.getElementById( widgetID );
      wRoot.style.backgroundColor = "#EEEEEE";
 
    // 產生輸入區
    var wInput = document.createElement( "input" );
      wRoot.appendChild( wInput );
 
    // 產生按鈕
    var wButton = document.createElement( "input" );
      wButton.type = "button";
      wButton.value = "顯示";
      wRoot.appendChild( wButton );
 
    // 產生顯示區
    var wDiv = document.createElement( "div" );
      wDiv.innerHTML = "尚未輸入";
      wRoot.appendChild( wDiv );
 
    // 設定按鈕按下的動作
    wButton.onclick = function(){
      wDiv.innerHTML = "您輸入的是:" + wInput.value;
    };
  };
 
   // 暫時沒用到的變數
  this.pValue = null;
}

如此一來,在網頁裡面,先定義一個 idTest 的 element(例如 <DIV ID="Test"></DIV>)後,再透過 JavaScript 程式:

var mUI = new UI_01();
mUI.createUI( "Test" );

就可以快速的產生一個輸入框、一個按鈕和一個用來顯示的 <DIV> 區域了~而只要按下按鈕後,顯示區域的所顯示的內容,就會從「尚未輸入」變成「您輸入的是: xxxxx」了!

當然,在這個簡單的例子裡,可能看不出來這樣有什麼好處;但是如果是複雜一點、而且有需要重複使用的元件,這樣寫應該是在某種程度上,可以增加可重新使用的效率的~

不過,當 Heresy 這樣照直覺寫的時候,接下來碰到的問題,則是 HTML DOM 的 element 裡的 callback function 的 scope 問題;要注意的,是在指定 HTML DOM Element 的 callback function 的時候。假設上面的例子,我們希望把它改成在按下按鈕時,把 UI_01pValue 的值變成 wInput 裡的值的話,Heresy 自己很直覺得寫法,會變成是:

wButton.onclick = function(){
    this.pValue = wInput.value;
};

但是實際上,這樣的寫法是不對的!因為實際上,在 wButton.onclick = function(){ … } 裡的 scope 和 this.createUI = function( widgetID ){ … } 的 scope 已經不一樣了!

this.createUI = function( widgetID ){ … } 裡,this 指的是 UI_01;而在 wButton.onclick = function(){ … } 裡,this 指的是則是 wButton。也因此,上面的寫法會變成是修改到 wButton.pValue 的值,而不是真正想要修改沒有 UI_01.pValue

遇到這樣的問題該怎麼解的?其實也很簡單,只要先用一個變數來記住 UI_01this 就好了~寫法可以寫成:

var rThis = this;
wButton.onclick = function(){
    rThis.pValue = wInput.value;
};

實際上,同樣的問題也會發生在呼叫函式上~但是也都可以用同樣的方法解決的。

至此,就算是 Heresy 最近在寫物件導向 JavaScript 的一點心得吧~ ^^"

這些技巧,基本上應該常常在寫的人,都會注意吧?寫下來,算是給 Heresy 自己做個筆記了。

對「HTML DOM 的 JavaScript 類別實作方法」的想法

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.