解决flash无法在一些浏览器下使用滚轮的BUG
有些朋友在做flash的时候,一定有过无法在一些浏览器下使用滚轮的BUG,今天我发两个类来解决这个问题。
package soul.js.JSMouseWheel { import flash.display.InteractiveObject; import flash.display.Stage; import flash.events.MouseEvent; import flash.external.ExternalInterface; import flash.utils.getTimer; public class MouseWheelEnabler { static private var initialised:Boolean = false; static private var currentItem:InteractiveObject; static private var browserMouseEvent:MouseEvent; static private var lastEventTime:uint = 0; static public var useRawValues:Boolean; static public var eventTimeout:Number = 50; //in milliseconds public static function init(stage:Stage, useRawDelta:Boolean = false ):void { if( !initialised ) { initialised = true; registerListenerForMouseMove( stage ); registerJS(); } useRawValues = useRawDelta; } private static function registerListenerForMouseMove( stage : Stage ) : void { //Generate a target and an internal mouse event so we can access //the mouse event properties when an external event is fired stage.addEventListener ( MouseEvent.MOUSE_MOVE, function(e:MouseEvent ):void {//build handler currentItem = InteractiveObject( e.target ); browserMouseEvent = MouseEvent( e ); }//build handler ); } private static function registerJS() : void { if( ExternalInterface.available ) { var id:String = 'mws_' + Math.floor(Math.random()*1000000); ExternalInterface.addCallback(id, function():void{}); ExternalInterface.call(MouseWheelEnabler_JavaScript.CODE); ExternalInterface.call("mws.InitMouseWheelSupport", id); ExternalInterface.addCallback('externalMouseEvent', handleExternalMouseEvent); } } private static function handleExternalMouseEvent(rawDelta:Number, scaledDelta:Number):void { var delta:Number; var curTime:uint = getTimer(); if (curTime >= eventTimeout + lastEventTime) {//dispatch if (useRawValues) {//use raw delta = rawDelta; }//use raw else {//use scaled delta = scaledDelta; }//use scaled 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))); } lastEventTime = curTime; }//dispatch } public static function getBrowserInfo():BrowserInfo {//getBrowserInfo if (ExternalInterface.available) {//get browser info var infoObj:Object = ExternalInterface.call("mws.getBrowserInfo"); var platformObj:Object = ExternalInterface.call("mws.getPlatformInfo"); var agent:String = ExternalInterface.call("mws.getAgentInfo"); return new BrowserInfo(infoObj, platformObj, agent); }//get browser info else {//null return null; }//null }//getBrowserInfo } } class MouseWheelEnabler_JavaScript { public static const CODE : XML = <script><![CDATA[ function() { // create unique namespace if(typeof mws == "undefined" || !mws) { mws = {}; } var userAgent = navigator.userAgent.toLowerCase(); mws.agent = userAgent; mws.platform = { win:/win/.test(userAgent), mac:/mac/.test(userAgent), other:!/win/.test(userAgent) && !/mac/.test(userAgent) }; mws.vars = {}; mws.browser = { version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1], safari: /webkit/.test(userAgent) && !/chrome/.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 mws.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; } mws.usingWmode = function( swf ) { if( typeof swf.getAttribute == "undefined" ) { return false; } var wmode = swf.getAttribute( "wmode" ); if( typeof wmode == "undefined" ) { return false; } return true; } //Debug logging mws.log = function( message ) { if( typeof console != "undefined" ) { console.log( message ); } else { //alert( message ); } } mws.shouldAddHandler = function( swf ) { if( !swf ) { return false; } return true; } mws.getBrowserInfo = function() {//getBrowserObj return mws.browser; }//getBrowserObj mws.getAgentInfo = function() {//getAgentInfo return mws.agent; }//getAgentInfo mws.getPlatformInfo = function() {//getPlatformInfo return mws.platform; }//getPlatformInfo mws.addScrollListeners = function() {//addScrollListeners // install mouse listeners if(typeof window.addEventListener != 'undefined') { window.addEventListener('DOMMouseScroll', _mousewheel, false); } window.onmousewheel = document.onmousewheel = _mousewheel; }//addScrollListeners mws.removeScrollListeners = function() {//removeScrollListeners // install mouse listeners if(typeof window.removeEventListener != 'undefined') { window.removeEventListener('DOMMouseScroll', _mousewheel, false); } window.onmousewheel = document.onmousewheel = null; }//removeScrollListeners mws.InitMouseWheelSupport = function(id) {//InitMouseWheelSupport //grab reference to the swf var swf = mws.findSwf(id); //see if we can add the mouse listeners var shouldAdd = mws.shouldAddHandler( swf ); if( shouldAdd ) { /// Mousewheel support _mousewheel = function(event) {//Mouse Wheel //Cover for IE if (!event) event = window.event; var rawDelta = 0; var divisor = 1; var scaledDelta = 0; //Handle scaling the delta. //This is becoming less and less useful as more browser/hardware combos emerge. if(event.wheelDelta) {//normal event rawDelta = event.wheelDelta; if(mws.browser.opera) { divisor = 12; } else if(mws.browser.safari && mws.browser.version.split(".")[0] >= 528) { divisor = 12; } else { divisor = 120; } }//normal event else if(event.detail) {//special event rawDelta = -event.detail; }//special event else {//odd event //Unhandled event type (future browser graceful fail) rawDelta = 0; scaledDelta = 0; //alert('Odd Event'); }//odd event if(Math.abs(rawDelta) >= divisor) {//divide scaledDelta = rawDelta/divisor; }//divide else {//don't scale scaledDelta = rawDelta; }//don't scale //Call into the swf to fire a mouse event swf.externalMouseEvent(rawDelta, scaledDelta); if(event.preventDefault) {//Stop default action event.preventDefault(); }//Stop default action else {//stop default action (IE) return false; }//stop default action (IE) return true; }//MouseWheel //set up listeners swf.onmouseover = mws.addScrollListeners; swf.onmouseout = mws.removeScrollListeners; }//Should Add }//InitMouseWheelSupport } ]]></script>; } |
package soul.js.JSMouseWheel { public class BrowserInfo {//BrowserInfo Class //Platforms public static const WIN_PLATFORM:String = "win"; public static const MAC_PLATFORM:String = "mac"; //public static const OTHER_PLATFORM:String = "other"; //Agents static public const SAFARI_AGENT:String = "safari"; static public const OPERA_AGENT:String = "opera"; static public const IE_AGENT:String = "msie"; static public const MOZILLA_AGENT:String = "mozilla"; static public const CHROME_AGENT:String = "chrome"; private var _platform:String="undefined"; private var _browser:String="undefined"; private var _version:String="undefined"; public function BrowserInfo(browserInfoObj:Object, platformObj:Object, agent:String) {//BrowserInfo if (!browserInfoObj || !platformObj || !agent) {//bail return; }//bail //set version _version = browserInfoObj.version; //Set platform for (var prop:String in browserInfoObj) {//check props if (prop != "version") {//check for platform if (browserInfoObj[prop] == true) {//found it _browser = prop; break; }//found it }//check for platform }//check props for (var platProp:String in platformObj) {//check props if (platformObj[platProp] == true) {//found it _platform = platProp; }//found it }//check props }//BrowserInfo public function get platform():String { return _platform; } public function get browser():String { return _browser; } public function get version():String { return _version; } }//BrowserInfo Class } |
这两个类的主要原理,是利用与js通信来滚动。使用的时候只需要MouseWheelEnabler.init(stage);就可以了
发表评论