Предотвратите прокрутку от запуска обработчика ng-click
Я работаю над реализацией жесткого жесткого диска типа iOS в строках таблицы HTML. Например, прокрутка влево на Site11
превратит его из стандартной строки:
![A standard HTML table]()
в удаляемую строку:
![A standard HTML table with a delete-able HTML row]()
У меня есть эта функциональность, работающая с директивой ng-swipe-left
. Однако у меня также есть директива ng-click
для каждой строки, которая переходит к другому представлению приложения. В настоящее время оба события запускаются, когда я выполняю салфетки в строке, за исключением случаев, когда салфетки заканчиваются на самом тексте "Site11", а не в другом месте внутри строки. Например, этот жест будет запускать как обработчики ng-click
, так и ng-swipe-left
:
![enter image description here]()
но этот жест вызовет только обработчик ng-swipe-left
:
![enter image description here]()
Как я могу предотвратить выполнение обработчика ng-click
, если в строке выполняется салфетка, независимо от того, где заканчивается салфетка?
Вот суть моей структуры HTML, которая определяет каждую строку:
<tr ng-repeat="item in items">
<td ng-click="openDetailPane()"
ng-swipe-left="$parent.swipeDeleteItemId = item.Id"
ng-swipe-right="$parent.swipeDeleteItemId = 'none'">
<div list-item></div>
</td>
<td>
<i class="fa fa-angle-right fa-2x" />
<span>{{item.ChildCount}}</span>
</td>
</tr>
Кнопка удаления определяется внутри директивы list-item
; это видно только в том случае, если его идентификатор соответствует свойству swipeDeleteItemId
на контроллере:
<div class="list-item">
<span>{{item.Name}}</span>
<div ng-class="{true: 'is-visible', false: ''}[item.Id === swipeDeleteItemId]">
<div class="delete-item-swipe-button"
ng-mousedown="$event.stopPropagation();"
ng-click="$event.stopPropagation();">Delete</div>
</div>
</div>
Я должен упомянуть, что я только пробовал это в настольных версиях Chrome и IE11 - я предполагаю щелчок и перетаскиваю из регистров мыши одинаково, чтобы проведите по экрану на мобильном устройстве.
Ответы
Ответ 1
Наконец-то я смог настроить среду разработки, чтобы я мог проверить свое приложение на реальном мобильном устройстве. Я больше не замечаю этого поведения - видимо, щелчок и перетаскивание не обязательно ведут себя одинаково с реальным проводом на мобильном устройстве.
Ответ 2
Я также встретил эту ситуацию, и я, наконец, нашел сложный способ сделать это.
$event.stopPropagation()
, упомянутый где-то, работает только в ngClick. Даже писать пользовательскую директиву прокрутки $swipe
с помощью event.stopPropagation()
не может предотвратить ngClick... Итак...
Служба $swipe
по умолчанию запускает события "touch" и "mouse". Также действуют директивы ngSwipeLeft и ngSwipeRight.
Поэтому, когда вы делаете салфетки, он вызывает события в следующем порядке:
- touchStart
- TouchMove
- touchEnd
- MouseDown
- MouseUp
- выберите
Я тестировал мышью drag not touch напрямую, но мое приложение будет работать на сенсорном экране на ПК, а салфетки на этом сенсорном экране будут эмулировать перетаскивание мышью. Таким образом, тип события $swipe
service "end" в моем приложении - "mouseup".
Затем вы можете использовать флаг, чтобы сделать что-то вроде этого:
<div ng-swipe-left="swipeFunc(); swiping=true;" ng-click="swiping ? ( swiping = false ) : clickFunc();">
...
</div>
или
<div ng-swipe-left="swipeFunc(); swiping=true;" ng-mouseup="clickFunc();" ng-click="swiping=false;">
...
</div>
с clickFunc()
следующим образом:
$scope.clickFunc = function() {
if( $scope.swiping ) { return; }
// do something
}
Это работает для меня. Надеюсь, это тоже полезно для вас.
Ответ 3
У меня такая же проблема и сейчас, и только на настольном браузере. Я думал, что preventDefault()
или stopImmediatePropagation()
сделает трюк, но нет. Тем не менее, я нашел решение для него. Попробуйте следующее:
angular.module('app', [])
.directive('noSwipeClick', function () {
return function(scope, elm) {
var el = angular.element(elm);
el.bind('click', function(e) {
if(scope.swipe.swiping === true) {
e.stopPropagation();
e.preventDefault();
}
});
};
});
И в вашем HTML:
<div class="list-item">
<span>{{item.Name}}</span>
<div ng-class="{true: 'is-visible', false: ''}[item.Id === swipeDeleteItemId]">
<div no-swipe-click class="delete-item-swipe-button"
ng-mousedown="$event.stopPropagation();"
ng-click="$event.stopPropagation();">Delete</div>
</div>
</div>
Не забудьте назначить $scope.swipe.swiping = true
в вашем контроллере при фактическом прокрутке и установить значение false при завершении