我有4个相同基本按钮对象(矩形)的实例。按钮Class称为LinkButton,名称为LinkButton,每个实例都是button_1,_2,_3和_4。我使用以下ActionScript:
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import fl.motion.MotionEvent;
this.button_1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage("http://google.com"));
this.button_2.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage("http://adobe.com"));
this.button_3.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage("http://amazon.com"));
this.button_4.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage("http://ask.com"));
function fl_ClickToGoToWebPage(url:String) {
navigateToURL(new URLRequest(url), "_blank");
}
当我从网络服务器发布和运行时,新的(空白)页面会打开google.com - 我不会点击,它会自动打开。但是,没有其他页面打开。当然,我真的只想在点击事件中打开这些URL。我在这做错了什么?
答案 0 :(得分:3)
原因是,当您为事件添加回调时,您将向其传递对函数的引用。
然而,您正在做的是传递函数的结果。 (因此,在您添加侦听器时,实际上是使用提供的值运行方法fl_ClickToGoToWebPage
。)
你想要的是这个:
this.button_1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage);
您可以通过几种不同的方式传递数据(网址)。
在处理程序中使用switch语句:
这个解决方案非常好,虽然可能不像其他方式那样封装,但它很简单。
//you get a reference to the button that was clicked with the event's current target property.
function fl_ClickToGoToWebPage(event:Event) {
var url:String;
switch(event.currentTarget){
case button_4:
url = "http://ask.com";
break;
case button_3:
url = "http://amazon.com";
break;
//etc for the other buttons
}
navigateToURL(new URLRequest(url), "_blank");
}
为每个按钮分配动态属性。
此解决方案是封装最多的,因为数据附加到实际按钮,但动态变量容易出现拼写错误等,并且不会被编译器检查。
//if button_1 is a MovieClip or other dynamic class, you can just make up a property on it like this:
this.button_1.url = "http://google.com";
this.button_1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage);
//..repeat for the rest of the buttons
//then, in the handler, the event.currentTarget is a reference to the button that was clicked:
function fl_ClickToGoToWebPage(event:Event) {
navigateToURL(new URLRequest(event.currentTarget.url), "_blank");
}
为您的LinkButton
创建一个类文件并添加公开的url
属性
这是最优雅的解决方案,但对于一个属性来说,它可能有点矫枉过正。创建一个名为LinkButton.as
的文件,并将其放在.fla。
将其添加到文件中:
package {
public class LinkButton extends MovieClip {
public var url:String;
}
}
尽管如此,更好的是将LinkButton
的所有功能封装到其自己的类文件中:
package {
public class LinkButton extends MovieClip {
public var url:String;
public function LinkButton(){
this.addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(e:MouseEvent):void {
if(!url) return;
navigateToURL(new URLRequest(url), "_blank");
}
}
}
//this way, all you have to do in your timeline is set the url of each button.
现在您拥有所有LinkButton
的网址属性,请使用此属性,方法与之前的解决方案相同。差异,现在你有编译时检查。
使用烦人的函数作为返回值
如果您需要动态添加侦听器或需要删除/重新添加侦听器,此解决方案很危险且容易出现内存泄漏。
这个想法是,你用你的参数调用一个函数,然后返回另一个用作处理程序的函数。
this.button_1.addEventListener(MouseEvent.CLICK, createButtonHandler("http://google.com"));
function createButtonHandler(url:String):void {
return function(e:Event){
navigateToURL(new URLRequest(url), "_blank");
}
}
这里的问题是你无法再次引用这个功能。因此,即使您从屏幕上删除了按钮并将其取消了占位符(变量),它也将永远保留在内存中。