我正在构建一个AIR桌面应用程序。有一次,应用程序加载了一个弹出窗口(基于s:Window的MXML组件),其中包含一个mx:HTML组件,用于加载本地(在应用程序目录中)html文件, blank.html 。 blank.html 中的相关元素是:
<script src="jw/jwplayer.js"/> <!--JW Player's JS-based Embedder-->
...
<div id="jwtarget" /> <!-- the target that the embedder will use -->
由于我想要使用的参数是在运行时确定的,因此我使用domWindow
属性来调用加载播放器的方法。这是一个有效的例子:
private function injectPlayer():void {
var playerVars:Object = {};
playerVars.flashplayer = "jw/player.swf";
playerVars.file = "http://www.archive.org/download/meet_john_doe_ipod/meet_john_doe_512kb.mp4";
playerVars.height = 360;
playerVars.width = 640;
try { // attempt to invoke the js function
htmlComponent.domWindow.jwplayer("jwtarget").setup(playerVars);
} catch(e:Error) {}
}
在页面完成加载时调用:
<mx:HTML id="htmlComponent" location="assets/blank.html" complete="injectPlayer()" />
一切正常。
现在回答这个问题。我需要能够将更复杂的playerVars
对象传递给函数,但我似乎没有得到正确的语法。这是我一直在尝试的最简单的例子:
private function injectPlayer():void {
var playerVars:Object = {};
//playerVars.flashplayer = "jw/player.swf";
playerVars.file = "http://www.archive.org/download/meet_john_doe_ipod/meet_john_doe_512kb.mp4";
playerVars.height = 360;
playerVars.width = 640;
playerVars.modes = [{"type":"flash","src":"jw/player.swf"}];
try { // attempt to invoke the js function
htmlComponent.domWindow.jwplayer("jwtarget").setup(playerVars);
} catch(e:Error) {}
}
此代码应创建与上述代码完全相同的内容,但无法执行。我假设我需要以某种方式更改语法,以允许对象数组(modes
)作为参数正确传递给js函数。
我尝试过各种各样的事情,例如将modes
作为字符串传递,或者将整个事情放在JSON.stringify()
之前,但无济于事。任何人都知道为参数构造复杂对象的正确方法吗?
其他详细信息,如果您现在还没有推断出它们:Flex 4.5.1是我正在构建的SDK,包括AIR 3.0扩展(这意味着定位到FP11)。
更新
我尝试过的其他配置,它确实有效:
playerVars.modes = {"type":"flash", "src":"jw/player.swf"};
但是,这仍然无法解决我应该能够在modes
属性中传递对象数组的问题。但至少这种方式会加载视频播放器。
更新更新:
所以,我从 jwplayer.js 中找到了这段代码,我怀疑播放器加载失败了:
if (typeof parsedConfig.modes == "string") {
_modes = _playerDefaults();
_modes[0].src = parsedConfig.modes;
} else if (parsedConfig.modes instanceof Array) { // I suspect this was eval'd as false
_modes = parsedConfig.modes;
} else if (typeof parsedConfig.modes == "object" && parsedConfig.modes.type) {
_modes = [parsedConfig.modes];
}
为了测试我的怀疑,我在 blank.html 中添加了以下功能:
<script type="text/javascript">
var instanceOfArrayTest = function(arr) {
return arr instanceof Array;
}
</script>
在我的ActionScript代码中尝试了以下内容:
trace([1,2,3] is Array); // true
trace(htmlComponent.domWindow.instanceOfArrayTest([1,2,3])); // false!!!!
所以,似乎问题是ActionScript没有将AS3 Array对象作为JS Array对象传递!
答案 0 :(得分:2)
尝试这样做:
playerVars.modes = [{type:"flash",src:"jw/player.swf"}];
答案 1 :(得分:1)
与call()类的ExternalInterface方法不同,当mx:HTML作为参数传递给JS函数时,它不会自动将AS3类转换为相应的JS类。相反,HTML Control维护了一个环境,其中保留了AS3类本机的方法和属性,并使JS可以直接访问它们。
如果JS函数需要JS Array对象,则必须使用JavaScript Window
对象显式创建JS Array以访问JS Array
构造函数。 HTML控件使用它的domWindow属性提供对此的访问。否则,无法将AS3阵列“转换”为JS阵列。
这是一个基本的例子:
var JSArray:Function = htmlComponent.domWindow.Array;
htmlComponent.domWindow.instanceOfArrayTest( JSArray(1,2,3) ); // true
对于使用JW Player的config参数的更复杂的例子:
playerVars.modes = JSArray({"type":"flash","src":"jw/player.swf"},{"type":"html5"});
创建一个包含两个对象的JS数组。
有关HTML控件中JavaScript环境的更多信息,请查看Adobe的使用Flex开发AIR应用程序的JavaScript in AIR部分。