Как preventDefault на якорных тегах?
предположим, у меня есть якорный тег, такой как
<a href="#" ng-click="do()">Click</a>
Как я могу запретить браузеру переходить к # in AngularJS ?
26 ответов
обновление: С тех пор я изменил свое мнение об этом решении. После большего развития и времени, потраченного на это, я считаю, что лучшее решение этой проблемы-сделать следующее:
<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.
по словам документы для ngHref вы должны быть в состоянии оставить href или сделать 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
объект в код
хотя Рено дал отличное решение
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Я лично обнаружил, что вам также нужно $ event.stopPropagation () в некоторых случаях, чтобы избежать некоторых побочных эффектов
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
будет моим решением
Итак, читая эти ответы, @Chris все еще имеет самый "правильный" ответ, я полагаю, но у него есть одна проблема, он не показывает "указатель"....
Итак, вот два способа решить эту проблему без необходимости добавлять курсор: стиль указателя:
-
использовать
javascript:void(0)
вместо#
:<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
-
использовать
$event.preventDefault()
наng-click
директива (так что вы не мусорите свой контроллер с DOM-related литература):<a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
лично я предпочитаю первое последнему. javascript:void(0)
имеет другие преимущества, которые здесь обсуждается. Существует также обсуждение "ненавязчивого JavaScript" в этой ссылке, которая пугающе недавняя и не обязательно напрямую применяется к угловому приложению.
вы можете сделать следующее
1.Удалить href
атрибут из anchor (a
) tag
2.Установите курсор указателя в css на ng click elements
[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 ng-click="do()">Click</a>
- потому что в соответствии с документами вы должны иметь возможность оставить href, а затем Angular будет обрабатывать предотвращение по умолчанию для вас!
вся эта вещь предотвращения по умолчанию сбивает меня с толку, поэтому Я создал JSFiddle там иллюстрируют, когда и где Angular предотвращает default.
JSFiddle использует директиву Angular - поэтому она должна быть точно такой же. Вы можете увидеть исходный код здесь: исходный код тега
Я надеюсь, что это поможет прояснить для некоторых.
Я хотел бы опубликовать документ в ngHref, но я не могу из-за моей репутации.
самый безопасный способ избежать событий на href-определить его как
<a href="javascript:void(0)" ....>
или если вам нужен inline, то вы можете сделать это:
<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>
многие ответы кажутся излишними. Для меня это работает
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</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();
}
})
}
};
}
])
я столкнулся с этой же проблемой при использовании якорей для углового загрузочного раскрывающегося списка. Единственное решение, которое я нашел, чтобы избежать нежелательных побочных эффектов (т. е. раскрывающийся список не закрывается из-за использования preventDefault()) должен был использовать следующее:
<a href="javascript:;" ng-click="do()">Click</a>
Если вы никогда не хотите идти в href... вы должны изменить разметку и использовать кнопку, а не тег привязки, потому что семантически это не привязка или ссылка. Наоборот, если у вас есть кнопка, которая выполняет некоторые проверки, а затем перенаправляет, она должна быть тегом ссылки / якоря, а не Кнопкой... для SEO целей тестирования [здесь вставить тестов].
для ссылок, которые вы только хотите перенаправить условно, как приглашение сохранить изменения или признать грязное состояние... вы должны использовать ng-click= " someFunction ($event)" и в someFunction на вашем validationError preventDefault и / или stopPropagation.
и просто потому, что вы можете не означает, что вы должны. javascript: void (0) хорошо работал в тот день... но из-за гнусных хакеров/взломщиков браузеры флаг приложений/сайтов, которые используют javascript в href... не вижу причин для ducktype выше..
Это 2016 с 2010 года должно быть никаких причин, что бы использовать ссылки, которые действуют как кнопки... если вам все еще нужно поддерживать IE8 и ниже, вам нужно переоценить свое место работы.
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
вы можете отключить перенаправление url внутри Html5Mode $location для достижения цели. Вы можете определить его внутри конкретного контроллера, используемого для страницы. Что-то вроде этого:--2-->
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);