Disable browser scrolling when using map.

1305
11
11-30-2010 11:32 AM
JasonLevine
Occasional Contributor II
Hello All,
If you've ever embedded a flex map into a browser, you've probably noticed that when you use the scroll wheel to zoom in or out, you also scroll the browser window as well. I was looking for a way to disable the browser window scrolling when you're over the map when I found MouseWheelTrap. Basically, you copy the following class package into your project, and then call for it in your main.mxml:

package com.esri.ags.script 
{
 import flash.display.Stage;
 import flash.errors.IllegalOperationError;
 import flash.events.Event;
 import flash.events.MouseEvent;
 import flash.external.ExternalInterface;
 
 /**
  * MouseWheelTrap - stops simultaneous browser/Flash mousewheel scrolling
  * @author Liam O'Donnell
  * @version 1.0
  * @usage Simply call the static method MouseWheelTrap.setup(stage);
  * @see http://www.spikything.com/blog/?s=mousewheeltrap for info/updates
  * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
  * © 2009 spikything.com
  */
 public class MouseWheelTrap
 {
  static private const JAVASCRIPT :String = "var browserScrolling;function allowBrowserScroll(value){browserScrolling=value;}function handle(delta){if(!browserScrolling){return false;}return true;}function wheel(event){var delta=0;if(!event){event=window.event;}if(event.wheelDelta){delta=event.wheelDelta/120;if(window.opera){delta=-delta;}}else if(event.detail){delta=-event.detail/3;}if(delta){handle(delta);}if(!browserScrolling){if(event.preventDefault){event.preventDefault();}event.returnValue=false;}}if(window.addEventListener){window.addEventListener('DOMMouseScroll',wheel,false);}window.onmousewheel=document.onmousewheel=wheel;allowBrowserScroll(true);";
  static private const JS_METHOD :String = "allowBrowserScroll";
  static private var _browserScrollEnabled :Boolean = true;
  static private var _mouseWheelTrapped :Boolean = false;
  private const INSTANTIATION_ERROR :String = "Don't instantiate com.spikything.utils.MouseWheelTrap directly. Just call MouseWheelTrap.setup(stage);";
  
  public function MouseWheelTrap()
  {
   throw new IllegalOperationError(INSTANTIATION_ERROR);
  }
  
  /// Sets up the Flash and the browser to deal with turning browser scrolling on/off as the mouse cursor enters and leaves the stage (a valid reference to stage is required)
  static public function setup(stage:Stage):void 
  {
   stage.addEventListener(MouseEvent.MOUSE_MOVE, function(e:* = null):void { allowBrowserScroll(false); } );
   stage.addEventListener(Event.MOUSE_LEAVE, function(e:* = null):void { allowBrowserScroll(true); } );
  }
  
  static private function allowBrowserScroll(allow:Boolean):void
  {
   createMouseWheelTrap();
   
   if (allow == _browserScrollEnabled)
    return;
   _browserScrollEnabled = allow;
   
   if (ExternalInterface.available) {
    ExternalInterface.call(JS_METHOD, _browserScrollEnabled);
    return;
   }
  }
  
  static private function createMouseWheelTrap():void
  {
   if (_mouseWheelTrapped) 
    return;
   _mouseWheelTrapped = true;
   
   if (ExternalInterface.available) {
    ExternalInterface.call("eval", JAVASCRIPT);
    return;
   }
  }
  
 }
 
}


Then you call it in your main.mxml with:
import com.esri.ags.script.MouseWheelTrap;
MouseWheelTrap.setup(stage);


This seems pretty straightforward, but I get the error, "1120: Access of undefined property stage" when I compile. There must be a simple fix to this that I'm not getting... Any Ideas?

Thanks for your help.
Tags (2)
0 Kudos
11 Replies
DasaPaddock
Esri Regular Contributor
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

   Have you tried
MouseWheelTrap.setup(parentApplication.stage);
0 Kudos
JasonLevine
Occasional Contributor II
Hi Robert,
  When I try that, I get "Access of undefined property parentApplication".

-Jason
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

   Strange... you said you are putting this in the main.mxml which is the main application right?

Well you could try this but it is basically the same thing:
MouseWheelTrap.setup(this.parentApplication.stage);
0 Kudos
JasonLevine
Occasional Contributor II
Robert,
  This gives the error "1042:The this keyword can not be used in static methods.  It can only be used in instance methods, function closures, and global code."

Yes, this is in the Main.mxml file which contains the map.

-Jason
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

   Can you attach you main.mxml? sounds like you are trying to use the code outside a function which is not allowed.
0 Kudos
JasonLevine
Occasional Contributor II
Hi Robert,
   Attached is my Main.mxml.  You're right, I was using it outside a function.  I created a creationcomplete function with it and although it compiled, it didn't work.

Thanks for your help,
Jason
0 Kudos
JasonLevine
Occasional Contributor II
I gave up on getting this to work and found an effective workaround:

Place the following code in the HEAD of your html page that has the embedded swf file:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.3.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
    dojo.addOnLoad(function() {
        var obj = dojo.byId("myId");
        if (obj) {
            var connection = dojo.connect(obj, dojo.isMozilla ? "DOMMouseScroll" : "onmousewheel", dojo.stopEvent);
            dojo.addOnWindowUnload(function() { dojo.disconnect(connection); }); // cleanup
        }
    });
</script>


It works pretty well.

-Jason
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

   Glad to hear that you got this worked out. I will make a mental note of this solution that worked.
0 Kudos