如何在Flash项目中实现Deeplink?

riadevID: 

首先解释一下Deeplink,在传统的WEB网站中,因为都是基于Page(页面)的应用,比如用户当前在A页面,那么当前的URL是(http://www.somedomain.com/a.html),然后通过一个超链接到达B页面,URL就变成了(http://www.somedomain.com/b.html)。如果用户想将B页面发给自己的一个好友,那么他只需要复制B页面的URL(http://www.somedomain.com/b.html),转发即可。非常简单,这是由HTML和浏览器的原生特性所支持的。

如果在RIA应用,比如Flash应用里面,这件事情就会变的困难一些,因为所有的状态切换,都在Flash内部完成,并没有涉及到URL的改变,还以上面的例子举例,用户打开了一个Flash站点,URL是(http://www.somedomain.com/flash.html),默认Flash给用户展示了内容A,然后用户在Flash里看到了很有趣的内容B,就从浏览器中复制了URL发给自己的好友,当好友打开这个URL(依然是http://www.somedomain.com/flash.html),很容易可以想到,他没有看到内容B。

那么如何在RIA应用里面,将状态与URL相关联起来呢?就是Deeplink技术。

关于Deeplink的实现,已经有一些框架,包括在Flex里面,已经有HistoryManager来支持,这里我们只讨论一些初级的情形,在不使用框架的情况下,实现简单的Deeplink。这需要从HTML和Flash内容本身两方面的结合来实现。

你可以从RIAMeeting站点Q/A专题,找到更多开发小技巧

HTML部分的实现 (依赖JavaScript)

首先我们要在HTML里面,用JavaScript声明一个方法,并被Flash调用。这个方法用来根据传递的值,改变页面的URL,注意代码中更改URL的时候,是以锚点的方式进行的,这也是HTML的一个特性,即:锚点链接是内部链接,不会刷新页面,这样产生的效果就是,虽然我们更改了URL,但页面不会随之刷新,保持了Flash站点不刷新的特性。

  1. <script>
  2. function changeLocation(l) {
  3. var base = String(document.location).split("#")[0];
  4. var tar = base+"#"+l;
  5. document.location = tar;
  6. }
  7. </script>

同样我们还要做一步工作,就是获取页面的URL,将#号之后的内容(如果有的话)取出来,传递给Flash,这是为了解决一旦用户打开了URL并以锚点的方式来标记要查看Flash中的特定内容,Flash可以根据传递的参数,显示该项内容。

  1. <script type="text/javascript">
  2. var locateFile = String(document.location).split("#")[1];
  3. var flashvars = {};
  4. if(locateFile != "") {
  5. flashvars.locateFile = locateFile;
  6. }
  7. var params = {allowscriptaccess:"always"};
  8. var attributes = {};
  9. swfobject.embedSWF("${swf}.swf", "myContent", "100%", "100%", "9.0.0", "expressInstall.swf",flashvars, params, attributes);
  10. </script>

Flash部分的实现

首先,在你的Flash中,切换状态的地方,加入如下的实现语句,然后你就可以观察,当Flash内容状态改变的时候,URL也发生了改变:

  1. if(ExternalInterface.available) {
  2. ExternalInterface.call("changeLocation","你定义的状态名称");
  3. } else {
  4. trace("不支持JS,无法使用DeepLink");
  5. }

然后在你的Flash初始化代码部分,增加对URL状态的判断,如果有用户传递的状态名称存在,则直接显示相应的状态:

  1. if(stage.loaderInfo.parameters.locateFile != "undefined") {
  2. locateFile = container.loaderInfo.parameters.locateFile;
  3. }

您给予的分值: None 平均分: 7 ( 10 票)

很常用的功能

做大一点的项目,尤其需要推广的项目时经常会用到

IE下的前进后退会有问题

这种方法只是将地址栏#后面的内容与flash页面联系起来,直接改变地址栏内容可以改变flash的页面,但在IE下前进后退的功能不能实现,因为#前面的内容不变的话IE是不会记录历史的。解决办法是搞一个隐藏的iFrame,当#后面的内容改变时修改iframe的url,从而使IE记录历史,实现前进后退。我html不熟悉,所以只知道大概,不晓得具体iframe怎么操作。
www.2advance.com就是这样实现前进后退的,可以把它的html和js都下下来研究研究。
另外#后面的内容在js里可以直接通过hash属性来读,不需要split:)

感谢你的补充,这个

感谢你的补充,这个例子只是简单说明Deeplink的原理,并没有实现前进后退的功能。通过测试可以发现,实际上浏览器是记录了浏览历史的,前进按钮和后退按钮都可点击,但是因为#前面的内容没有变化,所以页面不会刷新,Flash也不会重载。要解决这个问题,应该在HTML中加一个触发机制,侦听URL的更改,一旦发生更改,则呼叫Flash总的方法,改变Flash的状态。

这个在很多没有flash的

这个在很多没有flash的页面上使用过
比如视频网站的专辑播放页或者一个相册的专辑页上

非常实用的例子

这的确是个非常实用的例子,先回帖再细看

比较实用,不过,真

比较实用,不过,真的做起开发,就顾不上了,一般的客户也不怎么要求。不过真要做一款好的应用,这块还是超级有用的。

发表新评论

  • 网页地址和电子邮件地址将会被自动转换为链接。
  • 行和段被自动切分。
  • 您可以使用下面的标签来高亮显示您的评论内容: <code>, <blockcode>. 可以使用"[foo]".旁边显示标签样式 "<foo>" PHP代码可以用这样的区块来包含<?php ... ?> or <% ... %>

更多格式化选项信息

验证区域
系统验证:请回答下面的问题