Скажем, у меня есть якорный тег, например
<a href="#" ng-click="do()">Click</a>
Как я могу запретить браузеру переходить на # в AngularJS?
Скажем, у меня есть якорный тег, например
<a href="#" ng-click="do()">Click</a>
Как я могу запретить браузеру переходить на # в AngularJS?
ОБНОВЛЕНИЕ. С тех пор я решил изменить это решение. После большего развития и времени, потраченного на это, я считаю, что лучшим решением этой проблемы является следующее:
<a ng-click="myFunction()">Click Here</a>
И затем обновите свой css
, чтобы получить дополнительное правило:
a[ng-click]{
cursor: pointer;
}
Его гораздо проще и обеспечивает ту же функциональность и намного эффективнее. Надеюсь, что это может быть полезно для всех, кто ищет это решение в будущем.
Следующее - это мое предыдущее решение, которое я оставляю здесь только для устаревших целей:
Если у вас возникла эта проблема, простая директива, которая устраняет эту проблему, такова:
app.directive('a', function() {
return {
restrict: 'E',
link: function(scope, elem, attrs) {
if(attrs.ngClick || attrs.href === '' || attrs.href === '#'){
elem.on('click', function(e){
e.preventDefault();
});
}
}
};
});
Он проверяет все теги привязки (<a></a>
), чтобы узнать, является ли их атрибут href
пустой строкой (""
) или хешем ('#'
) или существует назначение ng-click
. Если он найдет какое-либо из этих условий, он поймает событие и предотвратит поведение по умолчанию.
Единственная нижняя сторона заключается в том, что она выполняет эту директиву для всех тегов привязки. Поэтому, если на странице есть много привязанных тегов, и вы хотите предотвратить поведение по умолчанию для небольшого числа, то эта директива не очень эффективна. Тем не менее, я почти всегда хочу preventDefault
, поэтому я использую эту директиву в своих приложениях AngularJS.
В соответствии с docs для ngHref вы должны уйти с href или do href= "".
<input ng-model="value" /><br />
<a id="link-1" href ng-click="value = 1">link 1</a> (link, don't reload)<br />
<a id="link-2" href="" ng-click="value = 2">link 2</a> (link, don't reload)<br />
<a id="link-4" href="" name="xx" ng-click="value = 4">anchor</a> (link, don't reload)<br />
<a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
Вы можете передать объект $event вашему методу и вызвать $event.preventDefault()
на нем, чтобы обработка по умолчанию не выполнялась:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
Я предпочитаю использовать директивы для такого рода вещей. Вот пример
<a href="#" ng-click="do()" eat-click>Click Me</a>
И код директивы для eat-click
:
module.directive('eatClick', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
event.preventDefault();
});
}
})
Теперь вы можете добавить атрибут eat-click
к любому элементу, и он автоматически получит preventDefault()
'.
Преимущества:
$event
в вашу do()
функцию.$event
.objectХотя Рено дал отличное решение
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Я лично нашел, что вам также нужно $event.stopPropagation() в некоторых случаях, чтобы избежать некоторых побочных эффектов
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
будет моим решением
Самое легкое решение, которое я нашел, это:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
ng-click="$event.preventDefault()"
Поэтому, читая эти ответы, @Chris все еще имеет самый "правильный" ответ, я полагаю, но у него есть одна проблема, он не показывает "указатель"....
Итак, вот два способа решить эту проблему, не добавляя курсора: стиль указателя:
Используйте javascript:void(0)
вместо #
:
<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
Используйте $event.preventDefault()
в директиве ng-click
(чтобы вы не загружали ваш контроллер ссылками, связанными с DOM):
<a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
Лично я предпочитаю первого над последним. javascript:void(0)
имеет другие преимущества, которые обсуждаются здесь. Существует также обсуждение "ненавязчивого JavaScript" в этой ссылке, которая пугающе недавно, и не обязательно непосредственно относится к приложению angular.
Вы можете сделать следующее:
1.Удалить атрибут href
из тега anchor (a
)
2. Установить курсор указателя в элементах css для ng click
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
HTML
здесь pure angularjs: рядом с функцией ng-click вы можете написать функцию preventDefault(), разделив точку с запятой
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">Click me</a>
JS
$scope.do = function() {
alert("do here anything..");
}
(или)
вы можете продолжить этот путь, это уже обсуждается здесь.
HTML
<a href="#" ng-click="do()">Click me</a>
JS
$scope.do = function(event) {
event.preventDefault();
event.stopPropagation()
}
Поскольку вы создаете веб-приложение, почему вам нужны ссылки?
Поменяйте привязки на кнопки!
<button ng-click="do()"></button>
если все еще актуально:
<a ng-click="unselect($event)" />
...
scope.unselect = function( event ) {
event.preventDefault();
event.stopPropagation();
}
...
Попробуйте этот параметр, который я вижу, еще не указан выше:
<a href="" ng-click="do()">Click</a>
Я бы пошел с:
<a ng-click="do()">Click</a>
Все это предотвращает меня по умолчанию, поэтому я создал JSFiddle там, где и где Angular предотвращает по умолчанию.
JSFiddle использует директиву Angular, поэтому она должна быть ТОЧНО одинаковой. Вы можете увидеть исходный код здесь: исходный код тега
Надеюсь, это поможет прояснить некоторые.
Мне бы хотелось опубликовать документ до ngHref, но я не могу из-за своей репутации.
Это то, что я всегда делаю. Работает как шарм!
<a href ng-click="do()">Click</a>
Самый безопасный способ избежать событий на href - определить его как
<a href="javascript:void(0)" ....>
Или, если вам нужна встроенная строка, вы можете сделать это:
<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>
Мне нужно наличие значения атрибута href для деградации (когда js отключен), поэтому я не могу использовать пустой атрибут href (или "#" ), но код выше не работал у меня, потому что мне нужно переменная события (e). Я создал свою собственную директиву:
angular.module('MyApp').directive('clickPrevent', function() {
return function(scope, element, attrs) {
return element.on('click', function(e) {
return e.preventDefault();
});
};
});
В HTML:
<a data-click-prevent="true" href="/users/sign_up" ng-click="openSignUpModal()">Sign up</a>
Заимствование из ответа на теннис. Мне нравится, что вам не нужно создавать настраиваемую директиву для добавления во все ссылки. Однако я не мог заставить его работать в IE8. Вот что, наконец, сработало для меня (используя angular 1.0.6).
Обратите внимание, что 'bind' позволяет использовать jqLite, предоставляемый angular, поэтому нет необходимости обертывать полным jQuery. Также требуется метод stopPropogation.
.directive('a', [
function() {
return {
restrict: 'E',
link: function(scope, elem, attrs) {
elem.bind('click', function(e){
if (attrs.ngClick || attrs.href === '' || attrs.href == '#'){
e.preventDefault();
e.stopPropagation();
}
})
}
};
}
])
Я столкнулся с этой проблемой при использовании якорей для бутстрапа angular. Единственное решение, которое я нашел, чтобы избежать нежелательных побочных эффектов (т.е. Падение вниз, не закрывающееся из-за использования preventDefault()), состояло в следующем:
<a href="javascript:;" ng-click="do()">Click</a>
если вы никогда не хотите идти в href... вы должны изменить свою разметку и использовать кнопку, а не тег привязки, потому что семантически это не привязка или ссылка. И наоборот, если у вас есть кнопка, которая выполняет некоторые проверки, а затем перенаправляет ее, это должен быть тег link/anchor, а не кнопка... для целей SEO, а также тестирование [вставить тестовый набор здесь].
для ссылок, которые вы только хотите перенаправить условно, как запрос на сохранение изменений или подтверждение грязного состояния... вы должны использовать ng-click = "someFunction ($ event)" и в someFunction на вашем validationError preventDefault и /stopPropagation.
также только потому, что вы можете не означать, что вы должны. javascript: void (0) хорошо зарекомендовал себя в день... но из-за гнусных хакеров/взломанных браузеров флаги приложений/сайтов, которые используют javascript внутри href... не видят причин для утиного типа выше.
в 2016 году с 2010 года не должно быть причин использовать ссылки, которые действуют как кнопки... если вам все еще нужно поддерживать IE8, а ниже вам нужно переоценить свое место деятельности.
Многие ответы кажутся излишними. Для меня это работает
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
Что вы должны сделать, полностью опускает атрибут href
.
Если вы посмотрите на исходный код для директивы элемента a
(которая является частью ядра Angular), это состояния в строке 29-31:
if (!element.attr(href)) {
event.preventDefault();
}
Это означает, что Angular уже решает проблему ссылок без href. Единственная проблема, с которой вы все еще сталкиваетесь, - проблема css. Вы все равно можете применить стиль указателя к якорям, у которых есть ng-клики, например:
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
Таким образом, вы даже можете сделать свой сайт более доступным, отметив реальные ссылки с тонким, другим стилем, а затем ссылками, которые выполняют функции.
Счастливое кодирование!
Вы можете отключить перенаправление URL-адресов внутри $location Html5Mode для достижения цели. Вы можете определить его внутри конкретного контроллера, используемого для страницы. Что-то вроде этого:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
Альтернативой может быть:
<span ng-click="do()">Click</span>