事件驅動的JScript面對象編程

來源:互聯網
上載者:User
js|jscript|編程|對象

  在這裡分享一下我對JScript的面對象編程的一些認識和一點解決方案。JScript和JavaScript差不多(當然有所不同),但本文中講到的內容也可用於JavaScript

  JScript支援面對象的一些屬性,但他的this指標很奇怪,當有一個對象obj1中的一個成員函數用到this,如果有別一個對象obj2引用該函數,那這個this指向的不是obj1,而是obj2。

下面我們來看一個例子:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>無標題文檔</title></head>
<body>
<p id="text">this is the element "p"</p>
<script language="jscript">
function obj1(){ //類obj1
     this.innerText = "this is obj1";
}
function obj1.prototype.fun(){
     alert(this.innerText);
}
var o1 = new obj1; //對象o1
o1.fun(); //顯示“this is obj1”
text.onclick = o1.fun; //把對象o1的成員函數綁定到HTML元素text中,這是再點擊“this is the element “p”。你會發現顯示的是this is the element “p”,而不是this is obj1。
</script>
</body></html>

  從上面的例子中我們可以知道JScrpt中函數引用只是引用了函數的入口,並沒有儲存對象的引用。而this只是簡單的指向調用函數的對象而已。JScript並無對象指標這種東西(可能我不知道,如果看文章的您知道的話,請告訴我(QQ:123737))。

  在我們通常寫一些要處理HTML元素的onclick事件的時候,我們會這樣寫

方法一:

<script language="jscript">

function fun(obj){

     alert(obj.innerText);

}

</script>

<p id="text" onclick="fun(this) ">element</p>



方法二:

<p id="text">element</p>

<script language="jscript">

function fun(){

     alert(this.innerText);

}

text.onclick = fun;

</script>

  上面兩個方法的動行結果是一樣的,可能你會探索方法一的onclick="fun(this) "直現一些。方法二的fun更理性些。但方法一的fun(this)的this太麻煩了,把代碼改成:

<script language="jscript">

function fun(){

     alert(this.innerText);

}

</script>

<p id="text" onclick="fun()">element</p>

  你會發現這個指令碼是不能工作的。為什嗎??當你用方法一書寫時,實際上這時onclick的處理事件是這樣的:

function anonymous() { fun(this) }

  也就是說IE為onclick事件創造了一個匿名函數,並在函數中調用了fun函數。由於調用anonymous的是對象text,所以this就把text的引用傳給了fun函數。這時fun中的形參obj就指向text。如果您把事件綁定寫成:

<p id="text" onclick="fun()">element</p>

  則由於調用fun()的是函數anonymous而不是對象text,所以如果您在fun中使用this的話,這裡this是不指向任何地方的。如果您alter(this)的話,您會發現他的值是undefined。

  在方法二中,onclick的處理事件就是fun,所以this是可用的,它指向text。但您千萬不要把方法二中fun的定義寫成:

function fun(obj){

     alert(obj.innerText);

}

  當text響應onclick事件調用onclick時是不傳遞任何參數給fun的,這時obj就是undefined了。

  問題已經明確,但當我們要響應HTML的事件,而處理的資訊又是存在於對象中時又該怎麼辦呢?(當然處理方法是基於純事件驅動的)

  我們可以這樣:

<p id="text">click this</p>

<script language="jscript">

function obj(){

     this.innerText = "this is obj";

}

function obj.prototype.fun(){

     var self = this.obj; //得到obj1的引用。學過Delphi的都知道self是什麼意思

//JScript中this是不能重新賦值的,所以用self。學過Delphi的人都知道self是什麼意思

     alert(self.innerText);

}

var obj1 = new obj;

text.obj = obj1;  //給text添加一個新的屬性obj,並賦於obj1的引用。

text.onclick = obj1.fun;

</script>

  點擊click this結果顯示"this is obj"。使用該方法就可以用JScript純事件驅動的程式了。

  說完了事件驅動的JScript面對象編程。我們來看看一個具體的例子:

  假如我們要在網頁上做一種可編輯的Label。正常情怳下它像一般的文本一樣。當用滑鼠點擊它時就變成輸入框並可編輯文本的內容。然後當它失去焦點時又恢複成正常文本的樣子。

  程式啟動並執行例子如下:

EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText

  程式的原始碼如下:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>無標題文檔</title>
</head>
<body>
<script language="jscript">
function EditableText(_owner){
this.owner = _owner;

this.edit = document.createElement("input");
this.edit.type = "text";
this.edit.onblur = this.onEditBlur;
this.edit.onclick = this.onEditClick;
this.edit.obj = this;

this.span = document.createElement("span");
this.span.innerText = "EditableText";
this.span.obj = this;
this.span.onclick = this.onSpanClick;

this.owner.appendChild(this.span);
}
function EditableText.prototype.onEditClick(){
event.cancelBubble = true;
}
function EditableText.prototype.onEditBlur(){
event.cancelBubble = true;
var self = this.obj;
self.span.innerHTML = "";
self.span.innerText = self.edit.value;
}
function EditableText.prototype.onSpanClick(){
event.cancelBubble = true;
var self = this.obj;
self.edit.value = this.innerText;
this.innerHTML = "";
this.appendChild(self.edit);
self.edit.focus();
}
////////////////////////////////////////////////////////////
function init(){
for(var i=0;i<20;i++){
new EditableText(document.body);
var br = document.createElement("br");
document.body.appendChild(br);
}
}
init();
</script>

</body>
</html>

  注意程式後面的init函數。裡面的new EditableText(document.body)只是建立了對象。但是我並無儲存建立的對象的引用。而是讓對象自己去管理自己。對象的行為都是由事件來驅動的(onclick和onblur),而無須別外的輔助代碼。

  程式啟動並執行例子如下:

EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText
EditableText

  程式的原始碼如下:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>無標題文檔</title>
</head>
<body>
<script language="jscript">
function EditableText(_owner){
this.owner = _owner;

this.edit = document.createElement("input");
this.edit.type = "text";
this.edit.onblur = this.onEditBlur;
this.edit.onclick = this.onEditClick;
this.edit.obj = this;

this.span = document.createElement("span");
this.span.innerText = "EditableText";
this.span.obj = this;
this.span.onclick = this.onSpanClick;

this.owner.appendChild(this.span);
}
function EditableText.prototype.onEditClick(){
event.cancelBubble = true;
}
function EditableText.prototype.onEditBlur(){
event.cancelBubble = true;
var self = this.obj;
self.span.innerHTML = "";
self.span.innerText = self.edit.value;
}
function EditableText.prototype.onSpanClick(){
event.cancelBubble = true;
var self = this.obj;
self.edit.value = this.innerText;
this.innerHTML = "";
this.appendChild(self.edit);
self.edit.focus();
}
////////////////////////////////////////////////////////////
function init(){
for(var i=0;i<20;i++){
new EditableText(document.body);
var br = document.createElement("br");
document.body.appendChild(br);
}
}
init();
</script>

</body>
</html>

  注意程式後面的init函數。裡面的new EditableText(document.body)只是建立了對象。但是我並無儲存建立的對象的引用。而是讓對象自己去管理自己。對象的行為都是由事件來驅動的(onclick和onblur),而無須別外的輔助代碼。



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。