【探索】用ActionScript模拟运行JavaScriptjavascript

来源:互联网 发布:关口知宏中国翻译 编辑:程序博客网 时间:2024/06/05 18:15

先来段简单的代码:

function jsdemo()

{

var doc = window.document;

var div = doc.createelement("div");

div.innerhtml = "hello! this box is created by javascript!";

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 = "

" + str + "

"

doc.body.appendchild(div);

}

function jsdemo1()

{

var doc = window.document;

var div = doc.createelement("div");

div.innerhtml = "hello! this box is created by actionscript!";

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; ivar 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。有兴趣的继续关注。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
原创粉丝点击