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!

11 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.

  10. Robby Lukaskiewicz Says:

    alright so I spent the last 20 mins looking for the same template you’re using and can’t find it. Didn’t want to have to ask but really would love to use it for my blog, could you let me know? I’ll look back here soon for any replies. Thank you

  11. Thijs Says:

    @Robby: you mean my WordPress theme? This is just the default theme which I modified a bit. I build the header with the Flickr images myself.

Leave a Reply