Issues with wmode=“opaque” and issues with wmmode=“window”

孤者浪人 提交于 2019-12-10 23:57:04

问题


Ok so first I was having 2 issues with default wmode of "window". My web page navigation menus would go under my flex/flash app. The other issue was when scrolling in the flash app the whole page would scroll.

I changed wmode to "opaque" and this fixed the issue with the navigation menus and so now they show up above the flash app. Thats great but now I dont have scrolling at all in the flash app.

I realize this is a big issue out there but I can't seem to find any solutions for solving both(actually 2.5 issues) of these problems.

I would like to A) Have navigation links show up above the flash app so they aren't hidden; B) Allow scrolling within the flash application; and C) Prevent scrolling of the web page if the mouse is over the flash app.

If you guys have any ideas that would be fantastic. :) Thanks in advance.


回答1:


What I meant when I wrote:

wmode=transparent & wmode=opaque behave the same as far as mousewheel.

is that both modes do not capture the MOUSE_WHEEL event in flash in most browsers (I believe IE is the only browser to capture the MOUSE_WHEEL event properly).

The solution is to listen for the MOUSE_WHEEL event via JavaScript:

//ie handles wmode=transparent correctly
//every other browser uses addEventListener
if ( !document.attachEvent )
{
  //console.log('attached');
  window.addEventListener('DOMMouseScroll', scrollListener, false);
  window.addEventListener('mousewheel', scrollListener, false);
}

scrollListener( e )
{
  var delta
  if ( e.wheelDelta )
  {
    delta = e.wheelDelta / 40;
  }
  else if ( e.detail )
  {
    delta = -e.detail;
  }
  //do stuff with delta
}

You'll then need to use ExternalInterface.addCallback to set up a callback for JS to alert flash that a MOUSE_WHEEL event took place.

wmode=transparent & wmode=opaque have issues with other mouse events as well.




回答2:


Fix for no MouseWheel in a Flex app when wmode="opaque" (it actually works in IE, just not Firefox or Chrome, probably not Safari or Opera either). This also fixes the different MouseWheel scroller rates between Firefox and everything else.

Add this JavaScript to your wrapper: .

        if(window.addEventListener) {
            var eventType = (navigator.userAgent.indexOf('Firefox') !=-1) ? "DOMMouseScroll" : "mousewheel";            
            window.addEventListener(eventType, handleWheel, false);
        }

        function handleWheel(event) {
            var app = document.getElementById("YOUR_APPLICATION");
            var edelta = (navigator.userAgent.indexOf('Firefox') !=-1) ? -event.detail : event.wheelDelta/40;                                   
            var o = {x: event.screenX, y: event.screenY, 
                delta: edelta,
                ctrlKey: event.ctrlKey, altKey: event.altKey, 
                shiftKey: event.shiftKey}

            app.handleWheel(o);
        }

And drop this support class into your main MXML file (Declarations for Flex4): .

package {
import flash.display.InteractiveObject;
import flash.display.Shape;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.geom.Point;

import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.FlexEvent;

public class MouseWheelSupport {

    //--------------------------------------
    //   Constructor 
    //--------------------------------------

    public function MouseWheelSupport() {
        FlexGlobals.topLevelApplication.addEventListener(FlexEvent.APPLICATION_COMPLETE, attachMouseWheelHandler);
    }

    //------------------------------------------------------------------------------
    //
    //   Functions  
    //
    //------------------------------------------------------------------------------

    //--------------------------------------
    //   Private 
    //--------------------------------------

    private function attachMouseWheelHandler(event : FlexEvent) : void {
        ExternalInterface.addCallback("handleWheel", handleWheel);
    }

    private function handleWheel(event : Object) : void {
        var obj : InteractiveObject = null;
        var applicationStage : Stage = FlexGlobals.topLevelApplication.stage as Stage;

        var mousePoint : Point = new Point(applicationStage.mouseX, applicationStage.mouseY);
        var objects : Array = applicationStage.getObjectsUnderPoint(mousePoint);

        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,
                                                     mousePoint.x, mousePoint.y, obj,
                                                     event.ctrlKey, event.altKey, event.shiftKey,
                                                     false, Number(event.delta));
            obj.dispatchEvent(mEvent);
        }
    }
}
}



回答3:


I was actually able to solve all three issues after that good link from zzzzBov. This lets me pass the mouse scrolling to the flash app while only doing this if the mouse is over the flash app. It also allows my flash app to stay in "opaque" mode so that it is not above the other HTML elements on the page.

An example of this is found here

Javascript

$(document).ready(function () {
        $('#MapSWFDiv').bind('mousewheel', function (event) {
            HandleMouseWheel(event);

            return false;
        });

        //Firefox
        $('#MapSWFDiv').bind('DOMMouseScroll', function (event) {
            HandleMouseWheel(event);

            return false;
        });
    });

    function HandleMouseWheel(event) {
        var app = GetMapSWF();
        if (app) {
            var delta = event.wheelDelta ? event.wheelDelta : event.detail;

            var o = { x: event.clientX, y: event.clientY,
                delta: delta,
                ctrlKey: event.ctrlKey, altKey: event.altKey,
                shiftKey: event.shiftKey
            }

            app.HandleMouseWheel(o);
        }
    }

Flex

protected function appComplete():void  {
    ExternalInterface.addCallback("HandleMouseWheel", HandleMouseWheel);
}

//This function passes the event to my map object. You could actually pass 
//it to any objects in the app that you would like. Also note that I am 
//getting the mouse coords from the flex app vs the actual browser. This keeps 
//everything local.
public function HandleMouseWheel(event:Object): void {
    var mEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_WHEEL, true, false,                     
        this.contentMouseX, this.contentMouseY, map, 
        event.ctrlKey, event.altKey, event.shiftKey, 
        false, -Number(event.delta));
    map.dispatchEvent(mEvent);
}


来源:https://stackoverflow.com/questions/5477426/issues-with-wmode-opaque-and-issues-with-wmmode-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!