Skip to content

Commit

Permalink
Better events and text selection
Browse files Browse the repository at this point in the history
Added better event handling, directive destroying and custom text
selection
  • Loading branch information
jellekralt committed Jul 31, 2015
1 parent 5d1aa8b commit 778e1de
Showing 1 changed file with 93 additions and 17 deletions.
110 changes: 93 additions & 17 deletions src/ng-drag-scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,102 @@
.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:
//<div drag-scroll>Lorem ipsum dolor sit amet</div>
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();
}

/**
* Handles mousemove event
* @param {object} e MouseMove event
*/
function handleMouseMove (e) {

if (pushed) {
if(!axis || axis === 'x') {
$element[0].scrollLeft -= (-lastClientX + (lastClientX = e.clientX));
Expand All @@ -68,6 +110,7 @@
}
}

e.preventDefault();
}

/**
Expand All @@ -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;

}

})();

0 comments on commit 778e1de

Please sign in to comment.