Prevent page scroll on mousewheel instead of Flash - Hack

If the HTML is larger than the browsers window, using the mouse-wheel will always result in a page scroll in AS3. That’s a bummer if you want to use the mouse-wheel inside the Flash.  This problem is better explained here.

After a lot of Googling I found out there wasn’t a good solution for this problem. So I build something that works.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package temple.utils
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
 
	/**
	 * This class prevents the mouse-wheel scrolling the page in the browser if the page is larger than the browsers window.
	 *
	 * Just call
	 *
	 * MouseWheelBlocker.init(this.stage);
	 *
	 * In the document class
	 *
	 * @author Thijs Broerse
	 */
	public class MouseWheelBlocker
	{
		private static var _initialized:Boolean;
		private static var _stage:Stage;
		private static var _textfield:TextField;
		private static var _enabled:Boolean;
 
		public static function init(stage:Stage):void
		{
			if(stage == null) throw new Error("stage can not be null");
 
			if(MouseWheelBlocker._initialized) return;
 
			MouseWheelBlocker._stage = stage;
			MouseWheelBlocker._textfield = new TextField();
			MouseWheelBlocker._textfield.width = MouseWheelBlocker._textfield.height = 100;
			MouseWheelBlocker._textfield.visible = false;
			MouseWheelBlocker._textfield.alpha = 0;
			MouseWheelBlocker._textfield.text = "";
			// add lots of new lines into the textfield
			for(var i:int = 0; i<100; i++)
			{
				MouseWheelBlocker._textfield.appendText("n");
			}
			MouseWheelBlocker._textfield.addEventListener(Event.SCROLL, MouseWheelBlocker.handleScroll);
			MouseWheelBlocker._stage.addChild(MouseWheelBlocker._textfield);
 
			MouseWheelBlocker.enable();
		}
 
		public static function get enabled():Boolean
		{
			return MouseWheelBlocker._enabled;
		}
 
		public static function set enabled(value:Boolean):void
		{
			if(value)
			{
				MouseWheelBlocker.enable();
			}
			else
			{
				MouseWheelBlocker.disable();
			}
		}
 
		public static function enable():void
		{
			if(!MouseWheelBlocker._enabled)
			{
				MouseWheelBlocker._stage.addEventListener(MouseEvent.MOUSE_WHEEL, MouseWheelBlocker.handleMouseWheel);
				MouseWheelBlocker._stage.addEventListener(MouseEvent.MOUSE_MOVE, MouseWheelBlocker.handleMouseMove);
				MouseWheelBlocker._enabled = true;
			}
		}
 
		public static function disable():void
		{
			if(MouseWheelBlocker._enabled)
			{
				MouseWheelBlocker._stage.removeEventListener(MouseEvent.MOUSE_WHEEL, MouseWheelBlocker.handleMouseWheel);
				MouseWheelBlocker._stage.removeEventListener(MouseEvent.MOUSE_MOVE, MouseWheelBlocker.handleMouseMove);
				MouseWheelBlocker._enabled = false;
			}
		}
 
		private static function handleMouseWheel(event:MouseEvent):void
		{
			MouseWheelBlocker._textfield.x = MouseWheelBlocker._stage.mouseX- MouseWheelBlocker._textfield.width * .5;
			MouseWheelBlocker._textfield.y = MouseWheelBlocker._stage.mouseY- MouseWheelBlocker._textfield.height * .5;
			MouseWheelBlocker._textfield.visible = true;
			new FrameDelay(MouseWheelBlocker.hide);
		}
 
		private static function handleMouseMove(event:MouseEvent):void
		{
			MouseWheelBlocker._textfield.x = MouseWheelBlocker._stage.mouseX- MouseWheelBlocker._textfield.width * .5;
			MouseWheelBlocker._textfield.y = MouseWheelBlocker._stage.mouseY- MouseWheelBlocker._textfield.height * .5;
		}
 
		private static function hide():void
		{
			MouseWheelBlocker._textfield.visible = false;
		}
 
		private static function handleScroll(event:Event):void
		{
			MouseWheelBlocker._textfield.scrollV = MouseWheelBlocker._textfield.maxScrollV * .5;
		}
	}
}

Just call

1
MouseWheelBlocker.init(this.stage);

In your document class (if the stage is available of course) and the page won’t scroll again when the mouse is in the Flash. Mouse-wheel still works inside the Flash.

You can download the source file here.

I know it’s actually a really dirty hack, but it’s the best solution I could make up. So if someone finds out a better solution, let me know!

9 Responses to “Prevent page scroll on mousewheel instead of Flash - Hack”

  1. Thijs Says:

    I found out it also has some problems in IE. :(

  2. bas Says:

    Hi, we have created a (commercial) solution in the form of a component that can solve exactly this problem. Called MouseWheelFix it a better mouse wheel enabler than most solutions and works with the browser (javascript) to accomplish its thing.

    Thought I should share…

  3. Thijs Says:

    @bas: looks nice. Unfortunatly it isn’t open-source… :-(

  4. bas Says:

    thx. But - no problems in IE - (sorry, could not resist :-) )

  5. tom Says:

    I’m very new to flash and trying to use this without success. Could you please explain where should I put this file and how to connect it? I’m using FlashCS4 Action Script 3 btw… Thanks!

  6. Thijs Says:

    tom >> If you’r familiar with ActionScript 3.0 it shouldn’t be a problem to you. Otherwise maybe you should read: http://www.moock.org/eas3/

  7. tom Says:

    Wow..now this is very clever, thanks!

  8. Martin Says:

    hey, could you publish the FrameDelay class too, its missing :(?

  9. Thijs Says:

    @Martin: The FrameDelay will be available in our ‘Temple’ framework soon. But for now you could use the FrameDelay class from ASAPLibrary: http://asaplibrary.org/
    It works the same.

Leave a Reply