`
showerliang
  • 浏览: 686 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Flex设置flash在html中所遇到的种种问题

 
阅读更多

第一次写,请见谅!

背景:

使用Flex做开发,碰到一些需求,要求能够在Flex开发的swf中嵌入其他html页面.

或者将swf嵌入到其他页面.

解决思路:

在swf嵌入其他页面:

利用Iframe来进行嵌入,或本页弹框,或本页框架嵌入 

网上有相关Flex开源的IFrame组件可供使用.名称叫 flex-iframe

在其他页面嵌入swf:

可以使用object 或者embed进行嵌入.也可以使用iframe引用一个object和embed包装的html页面

问题1描述: wmode 模式的选用 ,导致鼠标滚轮无效

wmode的三个模式分别为:window/Transparent/opaque

window:窗口模式,在没有指定wmode的时候,flash默认是以这种方式创建的。在这种模式下,flash拥有自己的窗口句柄,从而相对独立于浏览器的页面表现,独立的进行表现和渲染,所以窗口模式是相对其他模式来说效率最高的一种。同时也是因为它独立于浏览器的HTML渲染表面,所以当html的表现层和flash的表现层重合的时候,flash总是会遮住位置与他重合的所有html层。eg:你要做一个模态的提示框,想让灰色覆盖整个页面,但在有flash的情况,flash会不管你html中z-index的设置而表现在上层。 于是,就引出了第二种模式。

transparent :透明模式,这种模式类似于把flash放到html层结构里,可以通过z-index来进行层表现的传递和高度。在这种模式下flash会让可以透明的html层都以透明的方式展示在自己之上。这种对动画的性能表现的非常差,而且在9.0.115之前的flash player版本设置wmode=”transparent”会导致全屏模式失效。

Opaque:非透明模式,整个是相对于transparent方式来说的,它使flash隐藏html层上所有位于它后面的所有内容。

 

除了window模式外其他两个模式flash都没有自己的窗口句柄,表现力上会差很多.抛开表现上的差距,当非window模式下时,在Firefox/chrome浏览器下会发生事件滚轮无效的问题.ie9以上没有该问题,那么解决该问题的方法是:

通过js监听浏览器的鼠标滚轮事件,通过js和flash的function调用来实现对浏览器滚轮的实现.

具体做法如下:

 

if(!(document.all)) {
	   
	   if (document.addEventListener) {
	       window.addEventListener("DOMMouseScroll", onMouseWheelHandler, false);
	   }
	   window.onmousewheel = document.onmousewheel = this.onMouseWheelHandler; //Opera/Chrome 
	}
	function getFlashMovieObject(movieName){
		if (window.document[movieName]) {
			return window.document[movieName];
		}
		if (navigator.appName.indexOf("Microsoft Internet") == -1) {
			if (document.embeds && document.embeds[movieName])
				return document.embeds[movieName];
		}else {
			return document.getElementById(movieName);
		}
	}
	function onMouseWheelHandler(e){
	   var o = {x: e.screenX, y: e.screenY, delta: e.wheelDelta ? e.wheelDelta : -e.detail, ctrlKey: e.ctrlKey, altKey: e.altKey, shiftKey: e.shiftKey};
	   var vflash = getFlashMovieObject("${application}");
	   vflash.handleWheel(o);
	  
	};

 通过添加该段js脚本可以使得js可以调用flash为js注册的handleWheel方法.

 

在flex中我们需要添加该注册方法,在swf构建完毕后,添加如下内容

 

ExternalInterface.addCallback( "handleWheel" , handleWheel);  

 实现handleWheel方法

public function handleWheel(event:Object):void
			{
				var obj:InteractiveObject = null;
				var objects:Array = this.getObjectsUnderPoint(new Point(event.x, event.y));
				for (var i:int = objects.length - 1; i >= 0; i--) {
					if (objects[i] is InteractiveObject) {
						obj = objects[i] as InteractiveObject;
						break;
					} else {
						if (objects[i] is Shape && (objects[i] as Shape).parent) {
							obj = (objects[i] as Shape).parent;
							break;
						}
					}
				}
				
				if (obj) {
				var mEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_WHEEL, true, false, event.x, event.y, obj, event.ctrlKey, event.altKey, event.shiftKey,
							false, Number(event.delta) >0 ? 1:-1);
						obj.dispatchEvent(mEvent);

	
				}
			}

 

 

就可以实现在非window模式下 FF/Chrome 滚轮事件的响应了

问题2描述: wmode 模式的选用 ,导致鼠标滚轮无效-FireFox特殊处理

进行问题1的解决方法后,会发现在FireFox下仍然无效,解决方法是在flex中注册js调用方法前加入:

 

Security.allowDomain("*");
				Security.allowInsecureDomain("*"); 
 同意FireFox的js可以调用访问该域下swf的方法.

 

问题3描述: wmode 模式的选用 ,导致ComboBox无法打开使用的处理方式

由于鼠标的滚轮事件会通过js来传递给ComboBox,原combobox的鼠标监听事件无法使用,会导致在combobox打开的状态下,会认为js传来的事件是combobox的外部事件,那么combobox会自动关闭listbase.

解决方法,自己动手写一个combobox,将combbox的listbase打开关闭状态记录下来.当在接到外部js的滚轮事件时 && 并且 combobox的listbase处理打开状态,那么手动处理combobox的滚动.

代码如下:

 

package com.loyo.ui
{
	import flash.utils.Dictionary;
	
	import mx.controls.ComboBox;
	import mx.events.DropdownEvent;
	
	public class SelfComboBox extends ComboBox
	{
		public static var selfComboBoxNum:int = 0;
		public static var selfComboBoxDict:Dictionary = new Dictionary();
		public static function getSCombobox(id:String):SelfComboBox{
			return selfComboBoxDict[id];
		}
		public static function setSelfComboBox(id:String,scombobox:SelfComboBox):void{
			selfComboBoxDict[id] = scombobox;
		}
		
		public var isOpen:Boolean = false;
		
		public function SelfComboBox()
		{
			super();
			this.id = "scombobox_"+selfComboBoxNum;
			selfComboBoxNum++;
			setSelfComboBox(this.id,this);
			addEventListener(DropdownEvent.OPEN,onDropdownOpen);
			addEventListener(DropdownEvent.CLOSE,onDropdownClose);
		}
		
		public function onDropdownOpen(event:DropdownEvent):void{
			trace(" SelfComboBox isOpen :  true" );
			this.isOpen = true;
			
		}
		
		public function onDropdownClose(event:DropdownEvent):void{
			trace(" SelfComboBox isOpen :  false" );
			this.isOpen = false;
		}
		
		public function doMouseWheelByJS(delta:Number):void{
			if(isOpen){
				if(delta > 0){
					if(dropdown.selectedIndex > 0){
						dropdown.selectedIndex--;
					}
				}else{
					dropdown.selectedIndex++;
				}
				dropdown.scrollToIndex(dropdown.selectedIndex);
			}
			
		}
		
	}
}
 

 

----待续.. 有急事

问题5描述: wmode 模式的选用 ,IFrame嵌入swf包装页面html时,如何解决Iframe的滚轮不影响主页面

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics