Reputation: 26966
When using ng-click on a div:
<div ng-click="doSomething()">bla bla</div>
ng-click fires even if the user only selects or drags the div. How do I prevent that, while still enabling text selection?
Upvotes: 3
Views: 1512
Reputation: 121
I had to deal with this, too, and came up with something much simpler. Basically you store the x-position on mousedown and then compare new x-position on mouseup:
ng-mousedown="setCurrentPos($event)"
ng-mouseup="doStuff($event)"
Function setCurrentPos():
var setCurrentPos = function($event) {
$scope.currentPos = $event.offsetX;
}
Function doStuff():
var doStuff = function ($event) {
if ($event.offsetX == $scope.currentPos) {
// Only do stuff here, when mouse was NOT dragged
} else {
// Do other stuff, which includes mouse dragging
}
}
Upvotes: 1
Reputation: 2512
In requiring something similar, where the usual text selection behavior is required on an element which should otherwise respond to ngClick
, I wrote the following directive, which may be of use:
.directive('selectableText', function($window, $timeout) {
var i = 0;
return {
restrict: 'A',
priority: 1,
compile: function (tElem, tAttrs) {
var fn = '$$clickOnNoSelect' + i++,
_ngClick = tAttrs.ngClick;
tAttrs.ngClick = fn + '($event)';
return function(scope) {
var lastAnchorOffset, lastFocusOffset, timer;
scope[fn] = function(event) {
var selection = $window.getSelection(),
anchorOffset = selection.anchorOffset,
focusOffset = selection.focusOffset;
if(focusOffset - anchorOffset !== 0) {
if(!(lastAnchorOffset === anchorOffset && lastFocusOffset === focusOffset)) {
lastAnchorOffset = anchorOffset;
lastFocusOffset = focusOffset;
if(timer) {
$timeout.cancel(timer);
timer = null;
}
return;
}
}
lastAnchorOffset = null;
lastFocusOffset = null;
// delay invoking click so as to watch for user double-clicking
// to select words
timer = $timeout(function() {
scope.$eval(_ngClick, {$event: event});
timer = null;
}, 250);
};
};
}
};
});
Plunker: http://plnkr.co/edit/kkfXfiLvGXqNYs3N6fTz?p=preview
Upvotes: 2