Допустим, у меня есть тег привязки, такой как
<a href="#" ng-click="do()">Click</a>
Как я могу запретить браузеру переходить на # в AngularJS ?
href=''
чтобы сохранить поведение указателя мыши.
Допустим, у меня есть тег привязки, такой как
<a href="#" ng-click="do()">Click</a>
Как я могу запретить браузеру переходить на # в AngularJS ?
href=''
чтобы сохранить поведение указателя мыши.
Ответы:
ОБНОВЛЕНИЕ : с тех пор я передумал об этом решении. Я полагаю, что после долгих разработок и времени, потраченного на работу над этим, лучшее решение этой проблемы заключается в следующем:
<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.
href
атрибута в разных браузерах различно. Хотя я согласен, что это, безусловно, самое чистое и эффективное решение, у него есть некоторые проблемы с кроссбраузерностью. Использование директивного подхода позволяет браузеру обрабатывать <a>
тэг, как обычно, но все же получает OP ответ, который они искали.
В соответствии с документами для 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()
$event.preventDefault()
... IE налог.
ng-click="do(); $event.preventDefault()
например ... хотя, в этом нет необходимости, потому что приведенный ниже ответ @ Chris правильный. Это может помочь людям в ситуациях, когда они вложили ngClicks и хотят звонить $event.stopPropagation()
.
Я предпочитаю использовать директивы для такого рода вещей. Вот пример
<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
объектError: $ is not defined
. Чего мне не хватает?
angular.element(element).bind('click', function(event){...});
. Это сработало. Ref: jQLite
Хотя Рено дал отличное решение
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Я лично обнаружил, что в некоторых случаях вам также нужно $ event.stopPropagation (), чтобы избежать побочных эффектов.
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
будет моим решением
ng-click="$event.preventDefault()"
Самое простое решение, которое я нашел, это:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Итак, читая эти ответы, у @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», который пугающе недавний и не обязательно имеет прямое отношение к угловому приложению.
javascript:;
HTML
здесь чисто angularjs: рядом с функцией ng-click вы можете написать функцию protectDefault (), разделив точку с запятой
<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>
Самый безопасный способ избежать событий на href - это определить его как
<a href="javascript:void(0)" ....>
Я бы пошел с:
<a ng-click="do()">Click</a>
Вся эта штука с предотвращением по умолчанию сбивает меня с толку, поэтому я создал JSFiddle, чтобы проиллюстрировать, когда и где Angular предотвращает использование по умолчанию .
JSFiddle использует Angular как директиву, поэтому она должна быть точно такой же. Вы можете увидеть исходный код здесь: тег исходного кода
Я надеюсь, что это поможет разъяснения для некоторых.
Я хотел бы опубликовать документ на ngHref, но не могу из-за своей репутации.
Многие ответы кажутся излишними. Для меня это работает
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
Мне нужно наличие значения атрибута href для ухудшения (когда js выключен), поэтому я не могу использовать пустой атрибут href (или "#"), но приведенный выше код не сработал для меня, потому что мне нужно событие ( д) переменная. Я создал свою собственную директиву:
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();
}
})
}
};
}
])
dropdown
, я хочу распространение, но не поведение по умолчанию. Этот фрагмент НЕ рекомендуется.
Я столкнулся с этой же проблемой, когда использовал якоря для выпадающего углового загрузчика. Единственное решение, которое я нашел, чтобы избежать нежелательных побочных эффектов (т. Е. Раскрывающийся список не закрывался из-за использования protectDefault ()), заключалось в следующем:
<a href="javascript:;" ng-click="do()">Click</a>
если вы никогда не хотите переходить к href ... вам следует изменить разметку и использовать кнопку, а не тег привязки, потому что семантически это не привязка или ссылка. И наоборот, если у вас есть кнопка, которая выполняет некоторые проверки, а затем перенаправляет ее, это должен быть тег ссылки / привязки, а не кнопка ... для целей SEO, а также для тестирования [вставьте набор тестов здесь].
для ссылок, которые вы хотите перенаправить только условно, например, запрос на сохранение изменений или подтверждение грязного состояния ... вы должны использовать ng-click = "someFunction ($ event)" и в someFunction для вашего validationError предотвращать дефолт и / или stopPropagation.
также только потому, что вы можете не означает, что вы должны . javascript: void (0) хорошо работал в те времена ... но из-за гнусных хакеров / взломщиков браузеры помечают приложения / сайты, которые используют javascript внутри href ... не вижу причин для ввода типа выше ...
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();
});
}
};
});
Что вы должны сделать, это полностью опустить href
атрибут.
Если вы посмотрите на исходный код для a
директивы элемента (которая является частью ядра Angular), она указывает в строке 29–31:
if (!element.attr(href)) {
event.preventDefault();
}
Это означает, что Angular уже решает вопрос о ссылках без дополнительной информации. Единственная проблема, которая у вас осталась - это проблема css. Вы все еще можете применить стиль указателя к якорям, которые имеют ng-клики, например:
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
Таким образом, вы могли бы даже сделать свой сайт более доступным, пометив реальные ссылки тонким, отличающимся стилем от ссылок, которые выполняют функции.
Удачного кодирования!
Вы можете отключить перенаправление URL в Html5Mode $ location для достижения цели. Вы можете определить его внутри конкретного контроллера, используемого для страницы. Что-то вроде этого:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
Если вы используете Angular 8 или более, вы можете создать директиву:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[preventDefault]'
})
export class PreventDefaultDirective {
@HostListener("click", ["$event"])
public onClick(event: any): void
{
console.log('click');
debugger;
event.preventDefault();
}
}
На вашем теге привязки к компоненту вы можете подключить его так:
<a ngbDropdownToggle preventDefault class="nav-link dropdown-toggle" href="#" aria-expanded="false" aria-haspopup="true" id="nav-dropdown-2">Pages</a>
Модуль приложения должен иметь свою декларацию:
import { PreventDefaultDirective } from './shared/directives/preventdefault.directive';
@NgModule({
declarations: [
AppComponent,
PreventDefaultDirective
Альтернативой может быть:
<span ng-click="do()">Click</span>
span
кликабельными целями. Просто зайдите на @ теннисный ответ - якоря без href
определения.
href
.