From 778e1de1665a46925a776aba3d86a3c73a9b0d72 Mon Sep 17 00:00:00 2001 From: Jelle Kralt Date: Fri, 31 Jul 2015 14:33:13 +0200 Subject: [PATCH] Better events and text selection Added better event handling, directive destroying and custom text selection --- src/ng-drag-scroll.js | 110 +++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 17 deletions(-) diff --git a/src/ng-drag-scroll.js b/src/ng-drag-scroll.js index 34c5ce3..ad6e92c 100644 --- a/src/ng-drag-scroll.js +++ b/src/ng-drag-scroll.js @@ -5,52 +5,95 @@ .module('dragscroll') .directive('dragScroll', DragScroll); - DragScroll.$inject = ['$document', '$window']; + DragScroll.$inject = ['$document', '$window', '$parse']; /* @ngInject */ - function DragScroll($document, $window) { + function DragScroll($document, $window, $parse) { //Usage: //
Lorem ipsum dolor sit amet
var directive = { scope: false, restrict: 'A', link: function($scope, $element, $attributes, vm) { - var pushed = 0; + var allowedClickOffset = 5; + var pushed = false; + var onDragStart = $parse($attributes.onDragStart); + var onDragEnd = $parse($attributes.onDragEnd); var axis = $attributes.axis || false; + var startClientX; + var startClientY; var lastClientX; var lastClientY; // Set event listeners $element.on('mousedown', handleMouseDown); - angular.element($window).on('mouseup', handleMouseUp); - angular.element($window).on('mousemove', handleMouseMove); - // Handle destroy event + // Set destroy listener $scope.$on('$destroy', destroy); + /** + * Sets the event listeners for the mouseup and mousedown events + */ + function setDragListeners () { + angular.element($window).on('mouseup', handleMouseUp); + angular.element($window).on('mousemove', handleMouseMove); + } + + /** + * Removes the event listeners for the mouseup and mousedown events + */ + function removeDragListeners () { + angular.element($window).off('mouseup', handleMouseUp); + angular.element($window).off('mousemove', handleMouseMove); + } + /** * Handles mousedown event * @param {object} e MouseDown event */ function handleMouseDown (e) { - var dragAllowed = !('prevent-drag' in e.target.attributes); - if(dragAllowed) { - pushed = 1; - lastClientX = e.clientX; - lastClientY = e.clientY; + $scope.$apply(function() { + onDragStart($scope); + }); - //e.preventDefault(); - e.stopPropagation(); - } + // Set mouse drag listeners + setDragListeners(); + + // Set 'pushed' state + pushed = true; + lastClientX = startClientX = e.clientX; + lastClientY = startClientY = e.clientY; + + clearSelection(); + + e.preventDefault(); + e.stopPropagation(); } /** * Handles mouseup event * @param {object} e MouseUp event */ - function handleMouseUp () { - pushed = 0; + function handleMouseUp (e) { + var selectable = ('drag-scroll-text' in e.target.attributes); + var withinXConstraints = (e.clientX >= (startClientX - allowedClickOffset) && e.clientX <= (startClientX + allowedClickOffset)); + var withinYConstraints = (e.clientY >= (startClientY - allowedClickOffset) && e.clientY <= (startClientY + allowedClickOffset)); + + // Set 'pushed' state + pushed = false; + + // Check if cursor falls within X and Y axis constraints + if(selectable && withinXConstraints && withinYConstraints) { + // If so, select the text inside the target element + selectText(e.target); + } + + $scope.$apply(function() { + onDragEnd($scope); + }); + + removeDragListeners(); } /** @@ -58,7 +101,6 @@ * @param {object} e MouseMove event */ function handleMouseMove (e) { - if (pushed) { if(!axis || axis === 'x') { $element[0].scrollLeft -= (-lastClientX + (lastClientX = e.clientX)); @@ -68,6 +110,7 @@ } } + e.preventDefault(); } /** @@ -79,9 +122,42 @@ angular.element($window).off('mousemove', handleMouseMove); } + /** + * Selects text for a specific element + * @param {object} element Selected element + */ + function selectText (element) { + if ($window.document.selection) { + var range = $window.document.body.createTextRange(); + range.moveToElementText(element); + range.select(); + } else if ($window.getSelection) { + var range = $window.document.createRange(); + range.selectNode(element); + $window.getSelection().addRange(range); + } + } + + /** + * Clears text selection + */ + function clearSelection () { + if ($window.getSelection) { + if ($window.getSelection().empty) { // Chrome + $window.getSelection().empty(); + } else if ($window.getSelection().removeAllRanges) { // Firefox + $window.getSelection().removeAllRanges(); + } + } else if ($document.selection) { // IE? + $document.selection.empty(); + } + } + + } }; return directive; + } })();