原文链接:http://blog.csdn.net/mygisforum/article/details/16904207
1.问题产生
Flex 设置 wmode 属性为 opaque 或 transparent ,是为了解决flash 对象遮盖页面元素的问题。而随之而来产生了鼠标滚轮失效的问题,本人使用的Chrome浏览器,据说火狐也存在同样问题。
2.解决方法
解决方法主要是通过actionscript 中 ExternalInterface 的两个方法 addCallback 与 call 实现与浏览器 js 的鼠标事件的监听交互来实现的。以下代码来源于开源项目:flex-wmode-mousewheel-handler-example 和 EarthBrowser 。后经测试不兼容IE8,代码中已修正。
ActionScript 代码:
- package com.adobe.utils.mousewheel
- {
- import flash.display.InteractiveObject;
- import flash.display.Stage;
- import flash.events.MouseEvent;
- import flash.external.ExternalInterface;
- /**
- full credit goes to:
- http://blog.earthbrowser.com/2009/01/simple-solution-for-mousewheel-events.html
- */
- public class MouseWheelEnabler
- {
- static private var initialised : Boolean = false;
- static private var currentItem : InteractiveObject;
- static private var browserMouseEvent : MouseEvent;
- public static function init( stage : Stage ) : void
- {
- if( !initialised )
- {
- initialised = true;
- registerListenerForMouseMove( stage );
- registerJS();
- }
- }
- private static function registerListenerForMouseMove( stage : Stage ) : void
- {
- stage.addEventListener
- (
- MouseEvent.MOUSE_MOVE,
- function( e : MouseEvent ) : void
- {
- currentItem = InteractiveObject( e.target );
- browserMouseEvent = MouseEvent( e );
- }
- );
- }
- private static function registerJS() : void
- {
- if( ExternalInterface.available )
- {
- var id:String = 'eb_' + Math.floor(Math.random()*1000000);
- ExternalInterface.addCallback(id, function():void{});
- ExternalInterface.call(MouseWheelEnabler_JavaScript.CODE);
- ExternalInterface.call("eb.InitMacMouseWheel", id);
- ExternalInterface.addCallback('externalMouseEvent', handleExternalMouseEvent);
- }
- }
- private static function handleExternalMouseEvent(delta:Number):void
- {
- if(currentItem && browserMouseEvent)
- {
- currentItem.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_WHEEL, true, false,
- browserMouseEvent.localX, browserMouseEvent.localY, browserMouseEvent.relatedObject,
- browserMouseEvent.ctrlKey, browserMouseEvent.altKey, browserMouseEvent.shiftKey,
- browserMouseEvent.buttonDown,int(delta)));
- }
- }
- }
- }
JavaScript 代码段,直接写在ActionScript中,使用 ExternalInterface.call(MouseWheelEnabler_JavaScript.CODE); 调用。
- class MouseWheelEnabler_JavaScript
- {
- public static const CODE : XML =
- <script><![CDATA[
- function()
- {
- // create unique namespace
- if(typeof eb == "undefined" || !eb)
- {
- eb = {};
- }
- var userAgent = navigator.userAgent.toLowerCase();
- eb.platform =
- {
- win:/win/.test(userAgent),
- mac:/mac/.test(userAgent)
- };
- eb.vars = {};
- eb.browser =
- {
- version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
- safari: /webkit/.test(userAgent),
- opera: /opera/.test(userAgent),
- msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
- mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent),
- chrome: /chrome/.test(userAgent)
- };
- // find the function we added
- eb.findSwf = function(id)
- {
- var objects = document.getElementsByTagName("object");
- for(var i = 0; i < objects.length; i++)
- {
- if(typeof objects[i][id] != "undefined")
- {
- return objects[i];
- }
- }
- var embeds = document.getElementsByTagName("embed");
- for(var j = 0; j < embeds.length; j++)
- {
- if(typeof embeds[j][id] != "undefined")
- {
- return embeds[j];
- }
- }
- return null;
- }
- eb.usingWmode = function( swf )
- {
- if( typeof swf.getAttribute == "undefined" )
- {
- return false;
- }
- var wmode = swf.getAttribute( "wmode" );
- eb.log( "trying getAttributes: " + wmode );
- if( typeof wmode == "undefined" )
- {
- return false;
- }
- eb.log( "wmode: " + wmode );
- return true;
- }
- eb.log = function( message )
- {
- if( typeof console != "undefined" )
- {
- console.log( message );
- }
- else
- {
- //alert( message );
- }
- }
- eb.shouldAddHandler = function( swf )
- {
- if( !swf )
- {
- return false;
- }
- if( eb.platform.mac )
- {
- return true;
- }
- var usingWmode = eb.usingWmode( swf );
- // if( !eb.browser.msie && usingWmode ) return true;
- if(usingWmode ) return true;修复IE8滚轮失效的bug
- return false;
- }
- eb.InitMacMouseWheel = function(id)
- {
- var swf = eb.findSwf(id);
- var shouldAdd = eb.shouldAddHandler( swf );
- if( shouldAdd )
- {
- var mouseOver = false;
- /// Mouse move detection for mouse wheel support
- function _mousemove(event)
- {
- mouseOver = event && event.target && (event.target == swf);
- }
- /// Mousewheel support
- var _mousewheel = function(event)
- {
- if(mouseOver || (typeof mouseOver == 'undefined' && eb.browser.msie))
- {
- var delta = 0;
- if(event.wheelDelta)
- delta = event.wheelDelta / (eb.browser.opera ? 12 : 120);
- else if(event.detail)
- delta = -event.detail;
- if(event.preventDefault)
- event.preventDefault();
- swf.externalMouseEvent(delta);
- return true;
- }
- return false;
- }
- // install mouse listeners
- if(typeof window.addEventListener != 'undefined')
- {
- window.addEventListener('DOMMouseScroll', _mousewheel, false);
- window.addEventListener('DOMMouseMove', _mousemove, false);
- }
- else if(typeof window.attachEvent != 'undefined') //修复IE8滚轮失效的bug
- {
- document.attachEvent('onmousemove',_mousemove);
- document.attachEvent('onmousewheel',_mousewheel);
- }
- window.onmousewheel = document.onmousewheel = _mousewheel;
- window.onmousemove = document.onmousemove = _mousemove;
- }
- }
- }
- ]]></script>;
- }
3.使用示例
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
- layout="absolute" addedToStage="initMouseWheel()">
- <mx:Script>
- <![CDATA[
- import com.adobe.utils.mousewheel.MouseWheelEnabler;
- private function initMouseWheel() : void
- {
- MouseWheelEnabler.init( stage );
- }
- ]]>
- </mx:Script>
- </mx:Application>