欢迎来到 jackNEss'窝窝
I like simple mind

前端与flash交互相关知识整理

2012年09月29日

前端与flash交互相关知识整理

在说正事之前,先允许我吐个槽,想跳过的请点击 这里

最近的一些事

刚做完酷狗的抢鲜听项目之后,可以说是百感交杂。我突然发现前端的角色是多么的重要…

这个项目原来是北京那边负责的,而改版由广州总部这边发起,这个的后果就是——广州这边的产品经理、设计师、测试来负责这个项目的改版,而具体操刀改版工作的技术团队则由北京那边来提供。

然后 老板娘给出了一个比较超人的完成时间,再然后,就是的日理万机式的加班赶工了。结果,项目按时完工,验收却不通过。

之后就是陷入改bug 与验收的轮回里面了。这个项目,据我了解 7月份开始的,这个轮回一直去到9月,项目进入了可以说是接近报废的状态了。广州总部这边决定出手拯救这个不折不扣的烂项目。

小弟我 9月6日入职,当天下午就抓去开会充当了拯救队中的一员了,真是悲了个催的。先别说要我直接操刀.net页面了,这也小事,反正小弟不才好歹玩过.net 2年。打开项目一看,我擦,样式,页面结构,js 一塌糊涂:一个项目有2个 css目录,里面存在着和而不同的css样式文件(相同文件名,里面却又有大致相同,又不是全相同的样式)若干,修改样式起来各种蛋痛;没有模块化概念,几乎是一个页面一个css文件,即使2个页面的东西都差不多;各种兼容性问题;乱用 png24滤镜 从而引发大范围由这滤镜引起的bug;切图不会css splice,图片几乎全搞png24;页面结构不用说了,没数据的情况下全乱版,没什么语义化可言的 <p>标签里面有<div>的,<ul>标签套<div>的一大片;js 方面 就是各种全局污染,功能乱套;真是大开眼界,亮瞎了我的24K合金狗眼了。这只是单单前端这边的问题而已,后台的逻辑问题一大片,可以说作为一个烂项目,做得十分称职。

经过我们拯救小组日以继夜、日出而上班、几乎天天加班的连续2个星期的拯救中,项目终于面前流程能跑通,界面大致上没问题了(做的过程中我才发现原来北京的前端居然是只会切图不会重构的前端,这也叫前端么,应该叫前端切图师吧,亲。所以后台前端js什么的全部都由后端哥独挑大梁….难怪那么多前端bug)

直到项目上线,bugfree上提给拯救小组修复的bug一共300+,我擦呢,一个项目做成这样,也可以说是一个境界了。

在做这个项目的时候有个bug是关于前端和flash交互功能上的,我也发现自己在这方面了解的并不是很多,就顺便知识梳理下,也顺便为自己的库加上flash方面的功能接口。

下面就分享下我梳理到的相关知识

通过js加载flash

在没做这个项目之前…其实我是通过dw 的插入多媒体来把flash代码生成出来的,或者直接用embed标签调用,所以对这部分的代码没多研究,最多碰的就是wmode属性而已,之前都是flash哥亲自操刀,我不用、也不需要多管。

下面来说说 插入flash的这个<object>里面的那些参数都是做什么的。

<object id="object_name" name="name" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10.0.32" width="200" height="200">
	<param name="movie" value="test.swf" />
	<param name="flashvars" value="name=abc" />
	<param name="quality" value="high" />
	<param name="allowscriptaccess" value="always" />
	<param name="wmode" value="opaque"/>
	<embed id="embed_name" src="http://www.jackness.org/wp-content/themes/JStyle/images/default/blank.png" _src="test.swf" width="200"  height="200" allowscriptaccess="always" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="name=abc" type="application/x-shockwave-flash" wmode="opaque"></embed>
</object>

代码介绍

<object>标签是用于windows IE3.0及以后浏览器或者其它支持ActiveX控件的浏览器。“classid”和“codebase”属性必须要精确地按上例所示的写法写,它们告诉浏览器自动下载flash player的地址。如果你没有安装过flash player 那么IE3.0以后的浏览器会跳出一个提示框访问是否要自动安装flash player。当然,如果你不想让那些没有安装flash player的用户自动下载播放器,或许你可以省略掉这些代码。

<embed> 标签是用于Netscape Navigator2.0及以后的浏览器或其它支持Netscape插件的浏览器。“pluginspage”属性告诉浏览器下载flash player的地址,如果还没有安装flash player的话,用户安装完后需要重启浏览器才能正常使用。

为了确保大多数浏览器能正常显示flash,你需要把 <embed> 标签嵌套放在 <object> 标签内,就如上面代码例子一样。支持ActiveX控件的浏览器将会忽略 <object> 标签内的 <embed> 标签。Netscape和使用插件的IE浏览器将只读取 <embed> 标签而不会识别 <object> 标签。也就是说,如果你省略了 <embed>标签,那firefox就不能识别你的flash了(不过大家见那些视频网站的代码分享的,都是直接插 <embed>就ok的了 – - 嘛,时代在进步,没有做不到,只有你想不到)。

在这里,我们先看看 <object>标签中的属性各是有什么用的。

<object>标签属性介绍

定义一个嵌入的对象。请使用此元素向您的 XHTML 页面添加多媒体。此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码。

<object> 标签用于包含对象,比如图像、音频、视频、Java applets、ActiveX、PDF 以及 Flash。
object 的初衷是取代 img 和 applet 元素。不过由于漏洞以及缺乏浏览器支持,这一点并未实现。
浏览器的对象支持有赖于对象类型。不幸的是,主流浏览器都使用不同的代码来加载相同的对象类型。
而幸运的是,object 对象提供了解决方案。如果未显示 object 元素,就会执行位于 <object> 和 </object> 之间的代码。通过这种方式,我们能够嵌套多个 object 元素(每个对应一个浏览器)。

以下是 <object> 标签 在 flash 控件中 比较常用的 属性介绍。

属性名 介绍
width 必要属性。
设置 flash控件的宽度,单位为 百分比或象素 如:
width=”100%”
width=”500″
height 必要属性。
设置 flash控件的高度,单位为 百分比或象素 如:
height=”100%”
height=”500″
classid 必要属性。
设置浏览器的Activex控件
唯一值为 “clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″
codebase 设置flash Activex控件的位置,因而如果浏览器如果没有安装的话,可以自动下载安装。
唯一值为”http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10.0.32″(当然这版本什么的是随着更新换代而改变)

<object> 标签的其他属性可以查看 w3cshool

<param>标签属性介绍

<param> 标签允许您为插入 XHTML 文档的对象规定 run-time 设置,也就是说,此标签可为包含它的 <object> 或者 <applet> 标签提供参数。

在这里我就介绍下flash用到的一些比较常用的属性。

movie

<param name="movie" value="../test.swf" />

xxx.swf。
必要属性。
通过name与value定义指定要加载的 SWF 文件的名称。

wmode

<param name="wmode" value="opaque" />

选填属性。
通过name与value定义flash的窗口模式。
默认值为 window。

关于这个 wmode 属性 可以在我 这篇 文章里有进一步的介绍。

flashvars

选填属性。
通过name与value定义flash的参数传递变量形式和url的参数传递一样 如:”name=jackness&handsome=true&lover=suki”。

allowScriptAccess

<param name="allowScriptAccess" value="sameDomain" />

always | never | samedomain
选填属性。
通过name与value定义js与 flash应用程序之间的数据交换方式。
默认值为 samedomain。

  • always:外出脚本访问将始终成功。(flash与js方法可以互相调用,如果flash有注册的,js的方法是全局的话)
  • never:外出脚本访问将始终失败。(禁止互调)
  • sameDomain:仅当 SWF 文件和网页位于同一域中时才允许执行外出脚本访问。这是 AVM2 内容的默认值。(互调的前提是同域)

allowNetworking

<param name="allowNetworking" value="all" />

all | internal | none。
可以控制 SWF 文件对网络功能的访问。调用被禁止的 API 会引发 SecurityError 异常。
默认值为 all。

all

SWF 文件中允许使用所有网络 API。

internal

SWF 文件可能不调用浏览器导航或浏览器交互 API,但是它会调用任何其它网络 API。

设置为 “internal” 时,以下 API 被禁止:

navigateToURL()
fscommand()
ExternalInterface.call()

none

SWF 文件可能不调用浏览器导航或浏览器交互 API,并且它无法使用任何 SWF 到 SWF 通信 API。

设置为 “none” 时,除了上面列出的那些 API 外,还会禁止以下 API:

sendToURL()
FileReference.download()
FileReference.upload()
Loader.load()
LocalConnection.connect()
LocalConnection.send()
NetConnection.connect()
NetStream.play()
Security.loadPolicyFile()
SharedObject.getLocal()
SharedObject.getRemote()
Socket.connect()

play

<param name="play" value="true" />

true | false。
选填属性。
通过name与value定义指定flash影片是否在下载完成后就自动播放。
默认值为 true。

loop

<param name="loop" value="true" />

true | false。
选填属性。
通过name与value定义指定flash影片播放完最后一帧后是停止还是循环播放。
默认值为 true。

menu

<param name="menu" value="true" />

true | false。
选填属性。
通过name与value定义右键菜单内容。

  • true:显示全部的菜单,允许用户放大,缩小等控制影片播放等操作。
  • false:示只包含设置选项和关于flash的菜单。

quality

<param name="quality" value="high" />

low | autolow | autohigh | medium | high | best。
选填属性。
通过name与value定义嵌入内容的显示质量。
默认值为 high。

  • low:速度优于美观,而且不应用反锯齿。
  • autolow:刚开始着重于速度,但当需要时随时提升美观。
  • autohigh:同时着重播放速度和美观,但需要时则牺牲美观来保证播放速度。
  • medium:应用一些反锯齿而不平滑位图。它质量高于low设置而低于high设置。
  • high:美观优于播放速度,而且一直应用反锯齿。如果嵌入内容不包含动画,位图会被平滑化;而如果嵌入内容包含动画,位图将不变平滑。
  • best:提供最好的显示质量而不考虑播放速度。所有输出都应用反锯齿及所有位图都被平滑化。

scale

<param name="scale" value="showall" />

showall | noboder | exactfit | noscale。
选填属性。
通过name与value定义嵌入内容的拉伸方式。
默认值为 showall。

  • showall:嵌入内容在指定的区域内显示,但保持原始的比例。嵌入内容两侧将会出现边框。
  • noboder:收缩嵌入内容以适合指定的区域,保持嵌入内容不失真,但部分嵌入内容将可能将裁切。然而保持嵌入内容的原始比例。
  • exactfit:使整个嵌入内容在指定的区域内显示,嵌入内容有可能变形失真,而且不保持原始的比例。
  • noScale: 不对嵌入内容进行缩放处理,若嵌入内容过大,将进行裁切。

align

<param name="align" value="l" />

l | r | t 。
选填属性。
通过name与value定义嵌入内容的对齐方式。
默认情况下为水平垂直居中。

  • l:让嵌入内容相对于左对齐。
  • r:让嵌入内容相对于右对齐。
  • t:让嵌入内容相对于顶对齐。

salign

<param name="salign" value="tl" />

通过name与value定义嵌入内容缩放的参考点。
默认以中心作为参考点。

  • l:让嵌入内容以左侧作为缩放参考点。
  • r:让嵌入内容以右侧作为缩放参考点。
  • t:让嵌入内容以顶部作为缩放参考点。
  • b:让嵌入内容以底部作为缩放参考点。
  • tl:让嵌入内容以左上角作为缩放参考点。
  • tr:让嵌入内容以左下角作为缩放参考点。
  • bl:让嵌入内容以右上角作为缩放参考点。
  • br:让嵌入内容以右下角作为缩放参考点。

allowFullScreen

<param name="allowFullScreen" value="true" />

true | false。
通过name与value定义嵌入内容是否允许全屏,
默认不允许全屏。

bgColor

<param name="bgColor" value="#2266aa" />

通过name与value定义嵌入内容的背景色。

base

<param name="base" value="http://www.jackness.org/" />

通过name与value设置嵌入内容的相对参考路径。

devicefont

<param name="devicefont" value="false" />

true | false。
选填属性。
通过name与value定义即使未选择“设备字体”选项,也可指定静态文本对象是否以设备字体呈现。 如果操作系统具有需要的字体,则应用此属性。

<param>标签的其他属性可以查看 这里

<embed>标签属性介绍

embed可以用来插入各种多媒体,格式可以是 Midi、Wav、AIFF、AU、MP3等等,
Netscape及新版的IE 都支持。url为音频或视频文件及其路径,可以是相对路径或绝对路径。

对于 <embed>0 标签,所有在 <param> 中的设置(如 height、width、quality 和 loop)都是显示在起始 embed 标签的尖括号之间的属性

<embed wmode="transparent" src="http://www.jackness.org/wp-content/themes/JStyle/images/default/blank.png" _src="xxx.swf" allowScriptAccess="always" ></embed>

用于嵌入flash的 <embed> 标签属性包括 上面介绍的 所有 <param>属性。在这里就不重复了,下面介绍下 embed特有的一些属性。

属性 介绍
width 设置嵌入内容的宽度。单位为 px 或者 %
height 设置嵌入内容的高度。单位为 px 或者 %
src 设置潜入内容的flash源地址,如 xxx.swf
autostart true | false
是否自动播放。
默认值为 true
controls console | smallconsole | playbutton | pausebutton | stopbutton | voluelever
控制面板样式。
console:正常面板
smallconsole:小面板
playbutton:只显示播放按钮的面板
pausebutton:只显示暂停按钮的面板
stopbutton:只显示停止按钮的面板
volumelever:只显示音量调节按钮的面板
默认值为 console
hidden true | false
隐藏嵌入内容(也可以将高度宽度设置为0),通常用于声音。
默认值为 true
hspace 水平距离,单位像素
vspace 垂直距离,单位像素
loop 数字 | true | false
是否循环播放。
数字:循环次数
true:循环播放
false:不循环播放
默认值为 false
volume 取值0-100
音量大小,应根据系统确定音量

js插入flash代码

这个的原理其实就是通过js把嵌入flash使用到的 <object>、<param>、<embed>通过 document.write 或者 innerHTML 的方式插入到页面。
下面是我整合的 嵌入flash用 js 控件。

var jns = {};

/*
 * console
 * exp:jns.console("elm is undefined")
 * date: 2012-5-25
 * ver 1.0
 */
jns.console = function(msg){
	if(typeof console != "undefined"){
		console.log(msg);
	}
};

/*
 * flash 操作
 * date 2012-9-24
 * ver 1.0
 * 想js调用flash,在本地调试的话, 请在 http://www.macromedia.com/support/documentation/cn/flashplayer/help/settings_manager04.html 设置权限 chrome的话,只能丢网上或者架设个环境才能看到效果了
 */
jns.flash = {
	/*
	 * jns.flash.init(name,op) 初始化 flash对象,返回插入flash用的string代码
	 * arguments - name: 定义flash的名称,其中 <object> 的id 为 "object_" + name,<embed> 的id 为 "embed_" + name
	 * arguments - op:{
		wmode:  string类型,设置wmode的模式取值范围为 opaque|transparent|window, 默认为 opaque
		width:  number类型,设置flash对象的宽度值
		height: number类型,设置flash对象的宽度值
		flashvars: string类型,设置 flash对象的 flashvars值
		flashUrl: string类型,设置 flash对象的 地址
	 }
	 * date: 2012-9-26
	 * ver 1.0
	 */
	init:function(name,op){
		var option = {
			wmode:"opaque",// opaque|transparent|window
			width:300,
			height:300,
			flashvars:"",
			flashUrl:""
		};

		if(typeof op == "object"){
			if (typeof op.wmode != "undefined"){ 
				switch(op.wmode.toLowerCase()){
					case "opaque":
						option.wmode = "opaque";
						break;
					case "window":
						option.wmode = "window";
						break;
					case "transparent":
						option.wmode = "transparent";
						break;
				}option.wmode = op.wmode
			};
			typeof op.width != "undefined"? option.width = op.width:"";
			typeof op.height != "undefined"? option.height = op.height:"";
			typeof op.flashvars != "undefined"? option.flashvars = op.flashvars:"";
			typeof op.flashUrl != "undefined"? option.flashUrl = op.flashUrl:"";
		};
		if(option.flashUrl == ""){
			jns.console("jns.flash.write:flashUrl不能为空")
			return;
		}

		var writeHTML =[
			'<object id="object_' + name + '" name="' + name + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10.0.32" width="' + option.width + '" height="' + option.height + '">',
				'<param name="movie" value="' + option.flashUrl + '" />',
				'<param name="flashvars" value="' + option.flashvars + '" />',
				'<param name="quality" value="high" />',
				'<param name="allowscriptaccess" value="always" />',
				'<param name="wmode" value="' + option.wmode + '"/>',
				'<embed id="embed_'+ name +'" src="http://www.jackness.org/wp-content/themes/JStyle/images/default/blank.png" _src="' + option.flashUrl + '" width="' + option.width + '"  height="' + option.height + '" allowscriptaccess="always" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + option.flashvars + '" type="application/x-shockwave-flash" wmode="'+ option.wmode +'"></embed>',
			'</object>'
		].join("");
		return writeHTML;
	},
	/*
	 * jns.flash.write(name,op) 将flash对象通过 document.write 直接写在页面上
	 * arguments - name: 定义flash的名称,其中 <object> 的id 为 "object_" + name,<embed> 的id 为 "embed_" + name
	 * arguments - op:{
		wmode:  string类型,设置wmode的模式取值范围为 opaque|transparent|window, 默认为 opaque
		width:  number类型,设置flash对象的宽度值
		height: number类型,设置flash对象的宽度值
		flashvars: string类型,设置 flash对象的 flashvars值
		flashUrl: string类型,设置 flash对象的 地址
	 }
	 * date: 2012-9-26
	 * ver 1.0
	 */
	write:function(name,op){
		var writeHTML = this.init(name,op);
		if(writeHTML){
			document.write(writeHTML);
		};
	},
	/*
	 * jns.flash.add(target,name,op) 将flash对象添加到指定的容器里面
	 * arguments - target:目标对象
	 * arguments - name: 定义flash的名称,其中 <object> 的id 为 "object_" + name,<embed> 的id 为 "embed_" + name
	 * arguments - op:{
		wmode:  string类型,设置wmode的模式取值范围为 opaque|transparent|window, 默认为 opaque
		width:  number类型,设置flash对象的宽度值
		height: number类型,设置flash对象的宽度值
		flashvars: string类型,设置 flash对象的 flashvars值
		flashUrl: string类型,设置 flash对象的 地址
	 }
	 * date: 2012-9-26
	 * ver 1.0
	 */
	add:function(target,name,op){
		var innerHTML = this.init(name,op);
		if(!target){
			jns.console("jns.flash.add:对象为空");
			return;
		}
		if(innerHTML){
			target.innerHTML= innerHTML;
		};
	}
}	
	

调用方法 1:通过document.write()方法插入flash:

<div>
	<script type="text/javascript">
	jns.flash.write("flashObj",{width:200,height:200,flashUrl:"flash/test.swf"});	
	</script>
</div>	

调用方法 2:通过innerHTML方法插入flash:

<div id="flashDiv"></div>
<script type="text/javascript">
	var flashDiv = document.getElementById("flashDiv");
	jns.flash.add(flashDiv,"flashObj",{width:200,height:200,flashUrl:"flash/test.swf"});	
</script>	

js调用flash里面提供的方法

首先,如果想调用flash里面所写的一些方法如视频的 宽屏切换,关灯操作等,就必须flash那边注册相应的函数给js调用,同时 确保 allowScriptAccess = always

以下我简单写的一个在flash中注册方法的代码片段:

//ActionScript 3
import flash.external.ExternalInterface;
ExternalInterface.addCallback("callflash",callflash);
function callflash():void
{
	mytxt.text = "flash ctrl success!";
}	

其中 ExternalInterface.addCallback() 为我们上面所说的函数注册。 想进一步了解的话 可以参考官方说明 http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html

而在js方面,我们只要获取 这个 嵌入内容 的对象,就可以直接调用这个flash所提供的方法了。其中,我们所说的flash对象,在IE浏览器中为 <object> ,而在非IE浏览器下为 <embed>

假设我们事先嵌入的一个flash是这样结构

<object id="objectElm" name="name" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10.0.32" width="200" height="200">
	<param name="movie" value="test.swf" />
	<param name="flashvars" value="name=abc" />
	<param name="quality" value="high" />
	<param name="allowscriptaccess" value="always" />
	<param name="wmode" value="opaque"/>
	<embed id="embedElm" src="http://www.jackness.org/wp-content/themes/JStyle/images/default/blank.png" _src="test.swf" width="200"  height="200" allowscriptaccess="always" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="name=abc" type="application/x-shockwave-flash" wmode="opaque"></embed>
</object>	

那么,我们如果想调用 flash中 定义的 callflash() 方法,我们可以这样写:

var isIE = (navigator.appName.indexOf("Microsoft") != -1);
var thisMovie;
//IE浏览器
if(isIE){
	thisMovie = document.getElementById("objectElm");
}
//非IE浏览器
else{
	thisMovie = document.getElementById("embedElm");
}
thisMovie.callflash();

要注意的是,如果想在本地调试的话,请确保你flash的全局安全设置允许你flash的位置能与你的本地页面的数据正常传输交换,而 chrome浏览器的话,经过我测试,貌似只能丢网上或者架设个环境才能看到效果了,否则将提示错误说调用的方法为空。

设置地址: http://www.macromedia.com/support/documentation/cn/flashplayer/help/settings_manager04.html

下面是我整合的方法

jns.flash = {
	/*
	 * jns.flash.ctrl(name) 
	 * 获取 flash对象(主要用于调用flash提供的方法),只有通过 jns.flash.write()/jns.flash.add()方法添加上去的flash才受控制
	 * arguments - name:通过 jns.flash.write() 或者 jns.flash.add() 方法添加的flash对象中 的 name 值
	 * exp: jns.flash.ctrl("flashObj").f2s_alert();
	 * date: 2012-9-26
	 * ver 1.0 
	 */
	ctrl:function(name){
		var dc = document,
			embedElm = dc.getElementById("embed_" + name),
			objectElm = dc.getElementById("object_" + name);
		//非IE浏览器
		if(navigator.appName.indexOf("Microsoft") == -1){
			if(!embedElm){ 
				jns.console("jns.flash.ctrl: 非IE 下对象为空:" + "embed_" + name); 
				return;
			};
			return embedElm;
		
		} 
		//IE浏览器	
		else {
			if(!objectElm){ 
				jns.console("jns.flash.ctrl: IE 下对象为空:" + "object_" + name); 
				return;
			};
			return objectElm;
		};
	}
}	

调用方法:

jns.flash.ctrl("flashObj").callflash();	//其中callflash() 为 flash提供的方法

以上所说的 演示地址: http://www.jackness.org/lab/2012/js_flash/demo.html

如果出现错误说方法为空,很有可能是flash还没加载完成,导致事件还没注册好,从而引起的错误,所以我们这调用方法一般通过点击按钮来触发。

附录:flash全局安全设置简单介绍

这个安全设置,其实直接把你flash文件所在的硬盘分区设置为允许就ok了,下面有图有真相。

  • 1.勾选radio 选项的 “始终允许”。
  • 2.点击 “编辑多个位置…” 下拉框,选择 “添加位置” 选项。

  • 3.点击浏览文件夹来添加整个分区(chrome下点击[浏览文件]或者[浏览文件夹]都是只能选取单一文件…无语)

  • 4.选择你要添加的分区,然后按确定。

  • 5.完成。

呼…终于写完了,喵的,断断续续写了3天,全因为某项目上线了就马上开始优化了… ~>_<~ 雅蠛蝶

分类javascript
阅读 810
  • 评论加载中...

标签云

分类目录

最新留言

  • 评论加载中...

与我联系

如有疑问or建议可通过以下方式跟我取得联系.

Q Q:373435871
Email:jackness1208@gmail.com
© Copyright 2011 - 2014 jackNEss.org All Rights Reserved 粤ICP备14065612号
首页 | 关于我 | 网站地图 | RSS