Quellcode durchsuchen

consolidate mouse ignoring into a mixin

Adam Shaw vor 9 Jahren
Ursprung
Commit
82cea4affc
6 geänderte Dateien mit 71 neuen und 32 gelöschten Zeilen
  1. 1 0
      lumbar.json
  2. 17 13
      src/common/DragListener.js
  3. 0 13
      src/common/Grid.events.js
  4. 2 6
      src/common/Grid.js
  5. 27 0
      src/common/MouseIgnorerMixin.js
  6. 24 0
      src/util.js

+ 1 - 0
lumbar.json

@@ -20,6 +20,7 @@
         "src/common/Class.js",
         "src/common/EmitterMixin.js",
         "src/common/ListenerMixin.js",
+        "src/common/MouseIgnorerMixin.js",
         "src/common/Popover.js",
         "src/common/CoordCache.js",
         "src/common/DragListener.js",

+ 17 - 13
src/common/DragListener.js

@@ -3,7 +3,7 @@
 ----------------------------------------------------------------------------------------------------------------------*/
 // TODO: use Emitter
 
-var DragListener = FC.DragListener = Class.extend(ListenerMixin, {
+var DragListener = FC.DragListener = Class.extend(ListenerMixin, MouseIgnorerMixin, {
 
 	options: null,
 
@@ -15,6 +15,8 @@ var DragListener = FC.DragListener = Class.extend(ListenerMixin, {
 	originX: null,
 	originY: null,
 
+	// the wrapping element that scrolls, or MIGHT scroll if there's overflow.
+	// TODO: do this for wrappers that have overflow:hidden as well.
 	scrollEl: null,
 
 	isInteracting: false,
@@ -22,15 +24,18 @@ var DragListener = FC.DragListener = Class.extend(ListenerMixin, {
 	isDelayEnded: false,
 	isDragging: false,
 	isTouch: false,
-	isIgnoringMouse: false,
 
 	delay: null,
 	delayTimeoutId: null,
 	minDistance: null,
 
+	handleTouchScrollProxy: null, // calls handleTouchScroll, always bound to `this`
+
 
 	constructor: function(options) {
 		this.options = options || {};
+		this.handleTouchScrollProxy = proxy(this, 'handleTouchScroll');
+		this.initMouseIgnoring(500);
 	},
 
 
@@ -103,17 +108,10 @@ var DragListener = FC.DragListener = Class.extend(ListenerMixin, {
 			this.handleInteractionEnd(ev, isCancelled);
 
 			// a touchstart+touchend on the same element will result in the following addition simulated events:
-			// +mouseover
-			// +mouseout
-			// +click
-			//
+			// mouseover + mouseout + click
 			// let's ignore these bogus events
 			if (this.isTouch) {
-				var _this = this;
-				this.isIgnoringMouse = true;
-				setTimeout(function() {
-					_this.isIgnoringMouse = false;
-				}, 500);
+				this.tempIgnoreMouse();
 			}
 		}
 	},
@@ -152,7 +150,11 @@ var DragListener = FC.DragListener = Class.extend(ListenerMixin, {
 				}
 			});
 
-			if (this.scrollEl) {
+			// listen to ALL scroll actions on the page
+			if (
+				!bindAnyScroll(this.handleTouchScrollProxy) && // hopefully this works and short-circuits the rest
+				this.scrollEl // otherwise, attach a single handler to this
+			) {
 				this.listenTo(this.scrollEl, 'scroll', this.handleTouchScroll);
 			}
 		}
@@ -173,8 +175,10 @@ var DragListener = FC.DragListener = Class.extend(ListenerMixin, {
 	unbindHandlers: function() {
 		this.stopListeningTo($(document));
 
+		// unbind scroll listening
+		unbindAnyScroll(this.handleTouchScrollProxy)
 		if (this.scrollEl) {
-			this.stopListeningTo(this.scrollEl);
+			this.stopListeningTo(this.scrollEl, 'scroll');
 		}
 	},
 

+ 0 - 13
src/common/Grid.events.js

@@ -244,19 +244,6 @@ Grid.mixin({
 	},
 
 
-	// temporarily ignore mouse actions on segments
-	tempIgnoreMouse: function() {
-		this.isIgnoringMouse = true;
-		this.delayUnignoreMouse();
-	},
-
-
-	// delayUnignoreMouse eventually calls this
-	unignoreMouse: function() {
-		this.isIgnoringMouse = false;
-	},
-
-
 	handleSegTouchStart: function(seg, ev) {
 		var view = this.view;
 		var event = seg.event;

+ 2 - 6
src/common/Grid.js

@@ -2,7 +2,7 @@
 /* An abstract class comprised of a "grid" of areas that each represent a specific datetime
 ----------------------------------------------------------------------------------------------------------------------*/
 
-var Grid = FC.Grid = Class.extend(ListenerMixin, {
+var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
 
 	view: null, // a View object
 	isRTL: null, // shortcut to the view's isRTL option
@@ -30,10 +30,6 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, {
 	segResizeListener: null,
 	externalDragListener: null,
 
-	isIgnoringMouse: false, // bool
-	delayUnignoreMouse: null, // method
-
-
 
 	constructor: function(view) {
 		this.view = view;
@@ -41,7 +37,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, {
 		this.elsByFill = {};
 
 		this.dayDragListener = this.buildDayDragListener();
-		this.delayUnignoreMouse = debounce(proxy(this, 'unignoreMouse'), 1000);
+		this.initMouseIgnoring();
 	},
 
 

+ 27 - 0
src/common/MouseIgnorerMixin.js

@@ -0,0 +1,27 @@
+
+// simple class for toggle a `isIgnoringMouse` flag on delay
+// initMouseIgnoring must first be called, with a millisecond delay setting.
+var MouseIgnorerMixin = {
+
+	isIgnoringMouse: false, // bool
+	delayUnignoreMouse: null, // method
+
+
+	initMouseIgnoring: function(delay) {
+		this.delayUnignoreMouse = debounce(proxy(this, 'unignoreMouse'), delay || 1000);
+	},
+
+
+	// temporarily ignore mouse actions on segments
+	tempIgnoreMouse: function() {
+		this.isIgnoringMouse = true;
+		this.delayUnignoreMouse();
+	},
+
+
+	// delayUnignoreMouse eventually calls this
+	unignoreMouse: function() {
+		this.isIgnoringMouse = false;
+	}
+
+};

+ 24 - 0
src/util.js

@@ -344,6 +344,30 @@ function preventDefault(ev) {
 }
 
 
+// attach a handler to get called when ANY scroll action happens on the page.
+// this was impossible to do with normal on/off because 'scroll' doesn't bubble.
+// http://stackoverflow.com/a/32954565/96342
+// returns `true` on success.
+function bindAnyScroll(handler) {
+	if (window.addEventListener) {
+		window.addEventListener('scroll', handler, true); // useCapture=true
+		return true;
+	}
+	return false;
+}
+
+
+// undoes bindAnyScroll. must pass in the original function.
+// returns `true` on success.
+function unbindAnyScroll(handler) {
+	if (window.removeEventListener) {
+		window.removeEventListener('scroll', handler, true); // useCapture=true
+		return true;
+	}
+	return false;
+}
+
+
 /* General Geometry Utils
 ----------------------------------------------------------------------------------------------------------------------*/