Disable browser scrolling when using map.

1374
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
JohanMeijer
New Contributor III
Hi,

Should the javascript implementation also work on the flexviewer (we are still using V2.4) when embedded via an I-frame into another website, like: http://www.pbl.nl/en/roadsfromrio/trends-in-biodiversity-loss

Do I need to change the "myId" value to flashcontent?

For some reason the browser keeps scrolling...

I also can't get the MouseWheelTrap flex variant in action. Like JALevine mentions: it compiles without error, but no change in the website.

Any help appreciated!

Johan
0 Kudos
AaronNash1
Occasional Contributor II
I was able to get mouse trap working, not in the flexviewer but in an Iframe with a simple map. Displayed is the actionscript file, and just initialize this function on startup
   private function init():void
   { 
    MouseWheelTrap.setup(stage);
   }


package com.sample 
{
 
 import flash.display.Stage;
 import flash.events.Event;
 import flash.events.MouseEvent;
 import flash.external.ExternalInterface;
 import mx.core.Application;
 import mx.core.mx_internal;
 
 /**
  * MouseWheelTrap - Simultaneous browser/Flash mousewheel scroll issue work-around
  * @version 0.1
  * @author Liam O'Donnell
  * @usage Simply call the static method MouseWheelTrap.setup(stage)
  * @see http://www.spikything.com/blog/?s=mousewheeltrap for updates
  * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
  * (c) 2009 spikything.com
  */
 

public class MouseWheelTrap {
 
 static private var _mouseWheelTrapped :Boolean;
 
 public static function setup(mainStage:Stage):void {
  
  mx.core.FlexGlobals.topLevelApplication.addEventListener(MouseEvent.ROLL_OVER, function():void{ 
   allowBrowserScroll(false); 
  }
  );
  
  //i added 'mx.core.FlexGlobals.topLevelApplication.'making it work better for flex. use 'stage' for flash  
  mx.core.FlexGlobals.topLevelApplication.addEventListener(MouseEvent.ROLL_OUT, function():void{ 
   allowBrowserScroll(true); 
  }
  );
 }
 
 private static function allowBrowserScroll(allow:Boolean):void
 {
  createMouseWheelTrap();
  if (ExternalInterface.available){
   ExternalInterface.call("allowBrowserScroll", allow);
  }
 }
 private static function createMouseWheelTrap():void
 {
  if (_mouseWheelTrapped) {return;} _mouseWheelTrapped = true; 
  if (ExternalInterface.available){
   ExternalInterface.call("eval", "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;}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);");
  }
 }
}
}


I tried using the javascript, it worked when the map was embedded on the page but not when the map was in an iframe.
0 Kudos