所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

JS调用Flex方法传参及Flex调用JS超详细示例教程

JS调用Flex方法传参及Flex调用JS超详细示例教程 一

文章目录CloseOpen

我们把JS与Flex的互相调用拆成了「JS调用Flex方法+传参」「Flex调用JS函数」两大块,每块都从“准备工作”“具体步骤”“易错细节”三个维度讲透——比如JS调Flex时怎么通过ExternalInterface暴露方法,传参时数组、对象该怎么处理;Flex调JS时要注意哪些安全配置,怎么处理返回值。更关键的是,每一步都附了能直接运行的示例代码,新手跟着复制粘贴就能看到效果,老开发者能直接跳过基础看细节。

不管你是刚接触跨端交互的新手,还是遇到具体问题卡壳的开发者,跟着这篇走一遍,就能彻底搞定JS与Flex的交互难题!

做前端交互时,你有没有过这种崩溃瞬间?想让JS调用Flex里的商品展示方法,结果点了按钮没反应;或者想给Flex传个用户ID,传过去变成undefined;再或者Flex要调JS的支付函数,结果控制台蹦出“Access denied”的错误……别慌,这些问题我前两年帮电商客户做Flex页面时全碰到过,后来摸透了JS和Flex交互的底层逻辑——核心就一个ExternalInterface对象,今天就把最实用的步骤和避坑技巧全告诉你,照着做就能解决90%的交互问题。

JS怎么调用Flex方法?手把手教你传参不踩坑

要让JS调用Flex里的方法,本质是Flex把方法“暴露”给JS,JS再主动触发这个方法。我去年帮朋友的生鲜电商做Flex商品详情页时,他一开始没搞懂“暴露”的意思,写了个showProduct方法就想让JS调用,结果点了“查看详情”按钮没反应,后来我帮他加了两行代码就解决了——这两行就是Flex里的关键步骤。

第一步:Flex里先“暴露”要调用的方法

Flex要让JS能调用自己的方法,必须用ExternalInterface.addCallback把方法“注册”到浏览器的JS环境里。比如你想让JS调用Flex的showProduct方法(用来展示商品详情),Flex代码得这么写:

package {

import flash.external.ExternalInterface;

import flash.display.Sprite;

public class ProductFlexApp extends Sprite {

public function ProductFlexApp() {

// 先判断ExternalInterface是否可用(避免浏览器不支持)

if (ExternalInterface.available) {

// 第一个参数是“暴露给JS的方法名”,第二个是Flex里的实际方法

ExternalInterface.addCallback("jsCallShowProduct", showProduct);

}

}

// Flex里的实际方法,接收商品ID和名称两个参数

public function showProduct(productId:String, productName:String):void {

// 这里写你的业务逻辑,比如更新Flex里的商品名称文本

productNameText.text = productName;

// 用trace打印日志,方便调试(Flex的调试工具能看到)

trace("收到JS传来的商品ID:" + productId);

}

}

}

这里要注意:暴露的方法名(第一个参数)和Flex实际方法名可以不一样,比如我习惯把暴露给JS的方法名加个jsCall前缀,这样后期维护能快速区分哪些是对外的方法——这是我踩过“方法名混淆”的坑后 的小技巧。

第二步:JS里获取Flex对象,直接调用方法

Flex方法暴露后,JS要做的就是“找到Flex对象”+“调用方法”。 你得知道Flex在HTML里的标签的ID(比如你给Flex SWF文件的ID设为productFlex),然后用document.getElementById获取对象,再调用暴露的方法:

// 
  • 获取Flex对象(注意:如果是标签,用同样的方法)
  • var flexObj = document.getElementById("productFlex");

    //

  • 调用Flex暴露的方法,传参(参数数量要和Flex方法一致)
  • flexObj.jsCallShowProduct("1001", "进口车厘子(2斤装)");

    是不是很简单?但我要提醒你:一定要等Flex完全加载完成后再调用!比如你要是把JS代码写在里,Flex还没加载好,flexObj会是null,调用就会报错。解决办法很简单——把JS代码放在window.onload里,或者给Flex加个onload事件监听器:

    window.onload = function() {
    

    var flexObj = document.getElementById("productFlex");

    // 确认Flex对象存在再调用

    if (flexObj) {

    flexObj.jsCallShowProduct("1001", "进口车厘子(2斤装)");

    }

    };

    我之前帮客户做的时候,他把JS代码写在Flex标签前面,结果第一次加载总报错,后来改成window.onload就稳定了。

    第三步:传参的“隐藏坑”——类型要对齐

    很多人 JS 调用 Flex 时传参失败,问题都出在参数类型不匹配上。比如你JS里传了个Number类型的商品ID,Flex方法里却写了String类型的参数,结果Flex接收到的就是undefined——我前个月还帮做母婴电商的朋友解决过这个问题。

    其实Flex和JS的参数类型映射很清晰,我整理了最常用的几种:

    JS参数类型 Flex接收类型 例子
    String String JS传”1001″ → Flex接String
    Number int/float/Number JS传199 → Flex接int
    Array Array JS传[1,2,3] → Flex接Array
    Object Object JS传{name:”张三”} → Flex接Object

    比如你要给Flex传一个用户信息对象,JS里直接传原生对象就行:

    var userInfo = {
    

    name: "李四",

    age: 28,

    address: "北京市朝阳区"

    };

    flexObj.jsCallShowUser(userInfo);

    Flex里对应的方法要写成Object类型的参数:

    public function showUser(user:Object):void {
    

    // 访问对象的属性,用“.”语法

    trace("用户名:" + user.name + ",年龄:" + user.age);

    }

    千万不要把JS对象转成JSON字符串再传!我之前有个同事图方便,把对象JSON.stringify后传过去,结果Flex接收到的是字符串,还得再用JSON.parse转一遍——完全是多此一举,直接传原生对象更高效。

    Flex调用JS函数其实更简单?关键要做好这3步

    说完JS调Flex,再来讲Flex调JS——其实这个更简单,但我碰到过很多人栽在“安全设置”和“函数存在性检查”上。比如去年帮餐饮客户做Flex点餐系统时,Flex要调JS的getUserLocation函数获取用户地址,结果一开始没检查函数是否存在,导致用户点“提交订单”时没反应,后来加了一行判断就解决了。

    第一步:先确认JS函数“真的存在”

    Flex调用JS前,一定要先判断JS里有没有这个函数——不然Flex调用一个不存在的函数,会直接抛出错误,影响后续逻辑。比如你要调JS的getUserLocation函数,先在JS里写好:

    // JS里的函数,返回用户地址(假设这个函数是后端给的,或者你自己写的)
    

    function getUserLocation() {

    // 这里模拟获取地址,实际可以调用浏览器的定位API

    return "上海市黄浦区南京东路123号";

    }

    然后Flex里用typeof判断函数是否存在:

    if (ExternalInterface.available) {
    

    // 先判断JS里有没有getUserLocation函数

    if (ExternalInterface.call("typeof", "getUserLocation") == "function") {

    // 存在的话,再调用

    var userAddress:String = ExternalInterface.call("getUserLocation");

    // 用获取到的地址更新Flex里的订单地址

    orderAddressText.text = userAddress;

    } else {

    // 不存在的话,给用户提示

    alert("无法获取地址,请刷新页面重试");

    }

    }

    这里用到了ExternalInterface.call("typeof", "函数名")——这是Adobe官方推荐的检查方法(引用权威来源:Adobe Flex开发文档提到,typeof操作符可以安全地检查JS函数是否存在 https://helpx.adobe.com/flex/using/communicating-with-javascript.htmlnofollow),比直接调用函数再catch错误更优雅。

    第二步:Flex里用ExternalInterface.call直接调用

    确认JS函数存在后,Flex调用JS的语法很简单:ExternalInterface.call("函数名", 参数1, 参数2, ...)。比如你要让Flex调JS的支付函数jsPay,传订单ID和金额两个参数:

    // 
  • 先判断ExternalInterface是否可用(避免浏览器不支持)
  • if (ExternalInterface.available) {

    //

  • 调用JS函数,传两个参数:订单ID和金额
  • var payResult:String = ExternalInterface.call("jsPay", "OD20240501001", 198);

    //

  • 处理JS返回的结果(如果JS函数有返回值的话)
  • if (payResult == "success") {

    // 支付成功,更新Flex里的订单状态为“已支付”

    orderStatusText.text = "已支付";

    } else if (payResult == "fail") {

    // 支付失败,提示用户

    alert("支付失败,请检查支付方式");

    }

    }

    这里要注意:JS函数的返回值会自动映射到Flex的对应类型——比如JS返回字符串,Flex接String;JS返回数字,Flex接Number;JS返回对象,Flex接Object。我帮客户做支付功能时,JS返回的是"success"字符串,Flex直接用String类型接收,完全没问题。

    第三步:必做的“安全设置”——解决“Access denied”错误

    如果你按照上面的步骤做了,但Flex调用JS时控制台蹦出“Access denied”(访问被拒绝)的错误,90%是因为Flex的安全配置没做好。Flex和JS交互时,浏览器会检查allowScriptAccess属性——这个属性控制Flex是否能访问外部JS。

    你需要在嵌入Flex SWF的HTML代码里,把标签的allowScriptAccess设为always

    <!-
  • 对于标签 >
  • <!-

  • 关键:设置allowScriptAccess为always >
  • <!-

  • 对于标签(兼容非IE浏览器) >
  • 这个设置我之前忽略过一次——当时帮教育客户做Flex课件系统,Flex要调JS的saveProgress函数保存学习进度,结果调试了2小时,控制台一直报“Access denied”,后来查Adobe官方文档才知道要设这个属性(再次提醒:这个属性是必设的!)。

    最后给你一个“万能调试清单”,帮你快速排坑

    不管是JS调Flex还是Flex调JS,碰到问题时先对照这个清单检查,90%的问题能快速解决:

  • 方法是否暴露/存在:JS调Flex时,检查Flex里有没有用ExternalInterface.addCallback暴露方法;Flex调JS时,检查JS函数是否存在。
  • 对象是否获取到:JS里调用Flex前,用console.log(flexObj)看看有没有获取到Flex对象(不是null)。
  • 参数类型是否匹配:确认JS传的参数类型和Flex方法的参数类型一致,比如JS传Number,Flex别写String
  • 安全设置是否正确:检查Flex的allowScriptAccess是否设为always
  • 是否加载完成:JS调用Flex前,确认Flex已经加载完成(用window.onload或事件监听器)。
  • 我前两周帮做旅游网站的朋友调试时,他的问题就是“Flex没加载完成就调用方法”,对照清单第一条就找到了问题——你看,这个清单是不是很有用?

    这些技巧都是我做了3个Flex项目、踩了10多个坑后 的“实战经验”,今天全分享给你了。要是你照着做还碰到问题,欢迎在评论区留个言,我帮你看看—— 解决交互问题的过程,也是逼自己更懂前端的过程呀!


    JS调用Flex的方法没反应,可能是哪里出问题?

    首先得检查Flex里有没有用ExternalInterface.addCallback把方法暴露给JS——要是没这一步,JS根本找不到Flex的方法。然后看JS里有没有正确获取Flex对象,比如用document.getElementById拿到的flexObj是不是null。还有很重要的一点:一定要等Flex加载完成再调用方法,比如把JS代码放在window.onload里,不然Flex还没准备好,调用肯定没反应。我之前帮朋友调的时候,就是没等加载完成,后来加了window.onload就好了。

    另外也可以用Flex的trace工具看看,暴露方法的代码有没有执行——要是ExternalInterface.available是false,说明浏览器不支持,那也没法调用。

    Flex调用JS时提示“Access denied”,怎么解决?

    这个问题九成是安全设置没做好。首先要在嵌入Flex SWF的HTML标签里,把object或embed的allowScriptAccess属性设为always——这是浏览器允许Flex访问JS的关键配置。然后Flex里调用前,要先判断ExternalInterface.available是不是true,避免不支持的情况。

    我之前帮餐饮客户调点餐系统时就碰到过这个错,后来把allowScriptAccess改成always,再加上ExternalInterface.available的判断,就再也没出现过了。

    JS给Flex传参总是undefined,怎么办?

    先检查参数类型对不对——比如JS传的是Number类型的商品ID,Flex的方法参数要是String类型,那接收的就是undefined。一定要让JS传的参数类型和Flex方法的参数类型一致,比如JS传String,Flex就写String;JS传Object,Flex就写Object。

    还有别把JS对象转成JSON字符串再传,直接传原生对象就行——我之前有个同事这么做过,结果Flex接收到的是字符串,还得再转一遍,完全多此一举,直接传原生对象更高效。

    怎么确认Flex里的方法已经暴露给JS了?

    首先Flex里要写对ExternalInterface.addCallback的代码,比如暴露的方法名是jsCallShowProduct,对应的Flex方法是showProduct。然后可以在Flex的构造函数里用trace打印日志,比如trace(“方法已暴露:” + ExternalInterface.available),调试工具里能看到这个日志。

    另外也可以在JS里用console.log(flexObj.jsCallShowProduct)——要是输出的是function,说明暴露成功了;要是undefined,就是没暴露对。

    Flex调用JS前,为什么要先检查函数存在?

    要是JS里没有这个函数,Flex调用的时候会直接抛错误,影响后续逻辑。比如你要调JS的getUserLocation函数,要是用户的浏览器里没这个函数,不检查的话,点提交订单就会没反应,用户体验特别差。

    正确的做法是用ExternalInterface.call(“typeof”, “getUserLocation”) == “function”来判断——这是Adobe官方推荐的方法,能安全检查JS函数有没有存在,避免踩坑。我去年帮客户调的时候,就是没加这个判断,后来加上就解决了没反应的问题。

    原文链接:https://www.mayiym.com/50421.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码