Products
Technologies

Developer resources

Workaround to support mouse wheel for FireFox with wmode

Avg. Rating 4.4

Problem

There is an issue with mouse wheel in Flash Player when wmode attribute for embedding of swf is specified. See https://bugs.adobe.com/jira/browse/FP-289 for details. Here is a workaround for it.

Solution

The solution is to catch the mouse wheel in JavaScript inside of the html page that embeds swf. Then pass it into the swf component, where Flash code will generate mouse wheel event. The code samples below work under Flex 3 (SDK 3.1) and FireFox 2.0, though I believe the same solution can be used for other versions and for Flash.

Detailed explanation

Part 1. Catch mouse wheel in JavaScript

Below JavaScript code catches browser's mouse wheel event. Parameters of event are put into the object that then is passed into the SWF.

For Flex project, put this code into the index.template.html file in the html-template folder. If you do not use standard approach web page, place this code into the web page that embeds SWF, and put SWF name on place of.

Please, note that below code assumes that SWF is resized to the full size of the web page. If SWF is placed as part of the web page, correct x and y coordinates by adding the position of SWF on web page.

The code works under FireFox and completely ignored under IE browser. If you need to ignore other browsers, need to add appropriate browser checks.

<script language="JavaScript" type="text/javascript">
<!--
    if(!(document.attachEvent)) {
        window.addEventListener("DOMMouseScroll", handleWheel, false);
    }
    function handleWheel(event) {
        var app = window.document["${application}"];
        if (app) {
            var o = {x: event.screenX, y: event.screenY,
                delta: event.detail,
                ctrlKey: event.ctrlKey, altKey: event.altKey,
                shiftKey: event.shiftKey}
           
            app.handleWheel(o);
        }
    }
// -->
</script>

Part 2. Convert JavaScript event into Flash mouse event.

In the Flex application initialization, publish function to be accessible from JavaScript:

ExternalInterface.addCallback("handleWheel", handleWheel);

Then define following function:

public function handleWheel(event:Object): void {
    var obj:InteractiveObject = null;
    var objects:Array = 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));
        obj.dispatchEvent(mEvent);
    }
}

Above code gets list of all objects that are under mouse coordinates. Then we get the last (the most core) interactive object to pass event into. The new mouse event is created with parameters that are passed from JavaScript.

There is one simple difference between the behavior of this approach and the original Flex handling of mouse wheel: this approach does not account whether the scrollable container is active. With original approach, in IE browser, user require to click on the object (for example, grid) to enable mouse wheel for it. This approach scrolls immediately.

Report abuse

Related recipes