【探索】用ActionScript類比運行JavaScript

來源:互聯網
上載者:User

  先來段簡單的代碼:

function JSDemo()
{
var doc = window.document;
var div = doc.createElement("div");

div.innerHTML = "Hello! <i>This box is created by JavaScript!</i>";

div.style.background = "#CCC";
div.style.font = "bolder 18px 'Courier New'";
div.style.border = "1px dashed #693";

doc.body.appendChild(div);
}

  

  這是再簡單不過的JS代碼,最基本的DOM建立和操作。不過把他複製到ActionScript裡,它還能運行嗎?顯然不可能。雖然他們有著相似文法,但運行環境完全不同,當然是連編譯都通不過的。

  

  仔細思考下,AS3雖然是JavaScript2.0的風格,但也向下相容當前的JS文法。僅文法上說,JS複製到AS下是沒有語法錯誤的,只是變數沒有定義類型的提示的警告。但Flash SDK沒有提供Web的介面,所以window,document這些變數就不存在了,因此無法通過編譯。顯然,如果我們能夠提供這些介面,那麼代碼至少能通過編譯。

  

  縱觀Web下的各種介面,都是從window對象延伸開來。所以我們只需類比出window對象,之後其他對象就可以從這個頂級介面中擷取。由於不同瀏覽器下的介面都各不相同,並且錯綜複雜,所以手工的去類比每一個介面的功能是不現實的。因此我們需要一個AS和Web之間的代理程式,實現介面的自動轉換。

  

  ActionScript內建一個功能強大的類: flash.utils.Proxy。繼承它之後,我們的類就可以實現一些底層的操作。我們可以覆蓋對象預設的屬性讀寫,方法調用等等,類似C++的operator操作符。通過ExternalInterface.call,我們可以向Flash所在Web頁面進行互動,並返回資料,於是我們就可以實現AS/JS介面自動化代理程式了。

   

  例如,當訪問window對象的document屬性時,我們的getProperty重載函數向Web發送“ 擷取window的document屬性”指令。Web端的JS收到指令後,將document屬性從window對象讀取。不過由於document也是個對象,不是基本類型,所以不能直接返回給AS,而是將其儲存在數組裡,返回給AS一個對象序號,這個字串裡包含了數組的id位置。當以後訪問document的屬性時,這個代表document對象的序號就會傳遞過去,js就能從數組裡還原這個對象。

  

  不過要實現JS/AS函數變數的傳遞就要麻煩些。因為其中涉及到閉包等問題,所以僅僅傳遞函數字串是肯定行不通的。解決這個辦法,需要和儲存物件類型一個辦法:發送方在傳遞函數前先儲存起來,傳遞的只是一個序號;接收方收到序號後,建立一個代理函數,裡麵包含了這個序號。當以後被調用時,代理函數將序號作為參數通知給對方,對方通過序號從數組裡取出原函數,執行。

  

  這樣一個大致的輪廓就出來了:

  

  目前一些常用功能可以正常運行。下面寫了幾個簡單的JSDemo,能在ActionScript正常運行:

  http://www.etherdream.com/FunnyScript/RunJS/RunJS.html 

   

  不要忘了,這些JS可是運行在ActionScript環境下的!

   

package
{
import flash.display.*;


public class RunJS extends Sprite
{
private var window:JSEnv = JSEnv.$;


public function RunJS()
{
JSLine("DOM Demo:");
JSDemo1();

JSLine("Event Demo:");
JSDemo2();

JSLine("Closure Demo:");
JSDemo3();

JSLine("AJAX Demo:");
JSDemo4();
}


function JSLine(str)
{
var doc = window.document;
var div = doc.createElement("div");

div.innerHTML = "<p>" + str + "<hr/></p>"
doc.body.appendChild(div);
}


function JSDemo1()
{
var doc = window.document;
var div = doc.createElement("div");

div.innerHTML = "Hello! <i>This box is created by ActionScript!</i>";

div.style.background = "#CCC";
div.style.font = "bolder 18px 'Courier New'";
div.style.border = "1px dashed #693";

doc.body.appendChild(div);
}


function JSDemo2()
{
var doc = window.document;
var btn = doc.createElement("button");

btn.innerHTML = "Click Me!";
btn.onclick = function()
{
var i = 0;
window.setInterval(function()
{
btn.innerHTML = "Run in ActionScript: i=" + i++;
}, 10)
};

doc.body.appendChild(btn);
}


function JSDemo3()
{
var doc = window.document;

for(var i=0; i<5; i++)
{
var btn = doc.createElement("button");
doc.body.appendChild(btn);

btn.innerHTML = "Button" + i;
btn.onclick = (function(i)
{
return function(){window.alert(i)};
})(i);
}
}

function JSDemo4()
{
var doc = window.document;
var btn = doc.createElement("button");

doc.body.appendChild(btn);

btn.innerHTML = "Load Test.xml";

btn.onclick = function()
{
var xhr = window.ActiveXObject?
new window.ActiveXObject("Microsoft.XMLHTTP"):
new window.XMLHttpRequest;

xhr.onreadystatechange = function()
{
if(xhr.readyState != 4)
return;

window.alert(xhr.responseText);
};

xhr.open("GET", "Test.xml", true);
xhr.send();
};
}
}
}

  

   當然,目前仍有不少問題有待解決。這裡將繼續研究,借用ActionScript強大的IDE來調試JavaScript。並且升級之前的JS解譯器,將ActionScript解釋成更高效的JS。從而徹底拋棄混亂糾結的JS-OOP。有興趣的繼續關注。

相關文章

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.