In my angular application, the body has a ng-swipe
right and left to toggle a sidebar. The problem is when in my page I have a scrollable horizontal DIV. It won't scroll because of the swipe of the body.
<body ng-swipe-right="sidebar = true" ng-swipe-left="sidebar = false">
<div class="scrollable-x">long content that overflow on x</div>
</body>
Is there a way to prevent from swiping and to let the scroll of the child element?
I tried to set $event.stopPropagation()
on the swipe of the div so the scrollbar is not toggled anymore but the content won't scroll.
Any idea?
Looked at allenhwkim's answer and indeed he is correct, that $event
's propagation can be easily stopped. I took it for granted (without checking), that attaching ng-swipe-*
directive to other element will start firing separate events. I was clearly wrong.
HERE is updated fiddle.
The below answer is basically rubbish.
There is still one problem with stopPropagation
-- the mouse up event seems not to fire.
The most elegant solution would be to decorate the ng-swipe-*
directives or $swipe
service -- but looking into their code and I do not think it is possible.
Other option would be to create your own directive, that would manually attach ng-swipe-*
, take care of the compilation process and provide desired functionality. Surely, bit complicated.
What I came up with is a quick hack. The idea is to add an attribute to an element whose descendants should not fire the ng-swipe-*
.
myApp.value('shouldFire', function(element){
var update = true;
// strange enough $event.fromElement is always null
var current = element;
while(current && current != document.body){
if(current.getAttribute('swipe')=='cancel'){
update = false;
break;
}
current = current.parentElement;
}
return update;
})
function MyCtrl($scope, shouldFire) {
$scope.sidebar = false;
$scope.updateSidebar = function($event, show){
var element = $event.toElement || $event.srcElement;
shouldFire(element) && ($scope.sidebar = show);
}
}
<div class="cont" ng-swipe-right="updateSidebar($event, true)"
ng-swipe-left="updateSidebar($event, false)">
...
<div class="pan-container" panhandler=""
content-width="500px" swipe="cancel">
UPDATED DEMO
$event
stores a proper touch event (android's chrome) or a custom event (desktop's chrome); in the latter case $event.fromElement
is always null
.ng-swipe-*
handlers by setting different values in swipe
attribute.$event.stopProgagation()
must work. I don't know why yours not work.
http://plnkr.co/edit/AqczfhAVGMXNOcJij0JE?p=preview
var app = angular.module('myApp',['ngTouch']);
app.controller("MyCtrl", function($scope) {
$scope.void = function(evt){
evt.stopPropagation();
}
});
The common sense to me is that swiping and scroll left/right are different.
swiping is about moving fast. If you do not move fast. it's not swiping. When you scroll slowly, swiping does not happen.
I think all users know about this(maybe not). If not, I would recommend UX approach to let the user scroll slowly by showing some button or whatever, and leaving swipe as it is.
Anyhow, there is a way to disabling swipe using stopPropagation
Let me know if this plnkr does not satisfy your requirement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With