第一次写,请见谅!
背景:
使用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的滚轮不影响主页面