Powiedzmy, że mam tag zakotwiczenia, taki jak
<a href="#" ng-click="do()">Click</a>
Jak mogę uniemożliwić przeglądarce przejście do # w AngularJS ?
href=''
aby zachować zachowanie wskaźnika myszy.
Powiedzmy, że mam tag zakotwiczenia, taki jak
<a href="#" ng-click="do()">Click</a>
Jak mogę uniemożliwić przeglądarce przejście do # w AngularJS ?
href=''
aby zachować zachowanie wskaźnika myszy.
Odpowiedzi:
AKTUALIZACJA : Od tego czasu zmieniłem zdanie na temat tego rozwiązania. Po dalszym rozwoju i czasie poświęconym na pracę nad tym rozwiązaniem, uważam, że lepszym rozwiązaniem tego problemu jest wykonanie następujących czynności:
<a ng-click="myFunction()">Click Here</a>
A następnie zaktualizuj, css
aby mieć dodatkową regułę:
a[ng-click]{
cursor: pointer;
}
Jest o wiele prostszy i zapewnia dokładnie taką samą funkcjonalność oraz jest znacznie bardziej wydajny. Mam nadzieję, że może to być pomocne dla każdego, kto szuka tego rozwiązania w przyszłości.
Oto moje poprzednie rozwiązanie, które zostawiam tutaj tylko w celach starszych:
Jeśli często masz ten problem, prosta dyrektywa, która rozwiązałaby ten problem, jest następująca:
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();
});
}
}
};
});
Sprawdza wszystkie tagi anchor ( <a></a>
), aby sprawdzić, czy ich href
atrybut jest pustym ciągiem ( ""
) lub hashem ( '#'
), czy istnieje ng-click
przypisanie. Jeśli znajdzie którykolwiek z tych warunków, łapie zdarzenie i zapobiega domyślnemu zachowaniu.
Jedynym minusem jest to, że uruchamia tę dyrektywę dla wszystkich tagów zakotwiczenia. Jeśli więc masz na stronie wiele tagów zakotwiczenia i chcesz zapobiec domyślnemu zachowaniu tylko niewielkiej ich liczby, to ta dyrektywa nie jest zbyt wydajna. Jednak prawie zawsze chcę preventDefault
, więc używam tej dyrektywy w moich aplikacjach AngularJS.
href
atrybutu ma różne zachowanie w różnych przeglądarkach. Chociaż zgadzam się, że jest to zdecydowanie najczystsze i najbardziej wydajne rozwiązanie, ma pewne problemy z przeglądarkami. Użycie metody dyrektywy pozwala przeglądarce na obsługę <a>
tagu w normalny sposób, ale nadal uzyskuje OP żądaną odpowiedź.
Według dokumentacji dla ngHref powinieneś być w stanie zrezygnować z href lub zrobić 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 />
Możesz przekazać obiekt zdarzenia $ do swojej metody i wywołać $event.preventDefault()
go, aby domyślne przetwarzanie nie nastąpiło:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
$event.preventDefault()
... podatku IE.
ng-click="do(); $event.preventDefault()
na przykład ... chociaż nie jest to konieczne, ponieważ odpowiedź @ Chrisa poniżej jest poprawna. Może to pomóc ludziom w sytuacjach, w których zagnieżdżono ngClicks i chcą jednak zadzwonić $event.stopPropagation()
.
Wolę używać do tego celu dyrektyw . Oto przykład
<a href="#" ng-click="do()" eat-click>Click Me</a>
Kod dyrektywy dla eat-click
:
module.directive('eatClick', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
event.preventDefault();
});
}
})
Teraz możesz dodać eat-click
atrybut do dowolnego elementu, a zostanie on preventDefault()
zautomatyzowany.
Korzyści:
$event
obiektu do swojej do()
funkcji.$event
obiektuError: $ is not defined
. czego mi brakuje?
angular.element(element).bind('click', function(event){...});
. Zadziałało. Ref: jQLite
Chociaż Renaud dał świetne rozwiązanie
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Osobiście odkryłem, że potrzebujesz również $ event.stopPropagation () w niektórych przypadkach, aby uniknąć niektórych skutków ubocznych
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
będzie moim rozwiązaniem
ng-click="$event.preventDefault()"
Najłatwiejsze rozwiązanie, jakie znalazłem, to:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Więc czytając te odpowiedzi, @Chris nadal ma najbardziej „poprawną” odpowiedź, jak sądzę, ale ma jeden problem, nie pokazuje „wskaźnika” ....
Oto dwa sposoby rozwiązania tego problemu bez konieczności dodawania kursora: styl wskaźnika:
Użyj javascript:void(0)
zamiast #
:
<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
Użyj $event.preventDefault()
w ng-click
dyrektywie (aby nie blokować kontrolera referencjami związanymi z DOM):
<a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
Osobiście wolę ten pierwszy od drugiego. javascript:void(0)
ma inne zalety omówione tutaj . Dyskusja o „dyskretnym JavaScript” w tym linku, który jest przerażająco nowy i niekoniecznie dotyczy bezpośrednio aplikacji kątowej.
javascript:;
Możesz wykonać następujące czynności
1. Usuń href
atrybut ze a
znacznika anchor ( )
2.Ustaw kursor kursora w css, aby kliknąć elementy
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
HTML
tutaj pure angularjs: w pobliżu funkcji ng-click możesz napisać funkcję preventDefault () oddzielając średnik
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">Click me</a>
JS
$scope.do = function() {
alert("do here anything..");
}
(lub)
możesz postępować w ten sposób, ktoś już o tym tutaj dyskutuje.
HTML
<a href="#" ng-click="do()">Click me</a>
JS
$scope.do = function(event) {
event.preventDefault();
event.stopPropagation()
}
Skoro tworzysz aplikację internetową, dlaczego potrzebujesz linków?
Zamień kotwice na guziki!
<button ng-click="do()"></button>
Najbezpieczniejszym sposobem uniknięcia zdarzeń na hrefie byłoby zdefiniowanie go jako
<a href="javascript:void(0)" ....>
Poszedłbym z:
<a ng-click="do()">Click</a>
Całe to zapobieganie domyślnej rzeczy było dla mnie mylące, więc stworzyłem JSFiddle tam, aby zilustrować, kiedy i gdzie Angular uniemożliwia domyślne .
JSFiddle używa dyrektywy Angulara - więc powinno być DOKŁADNIE takie samo. Możesz zobaczyć kod źródłowy tutaj: kod źródłowy tagu
Mam nadzieję, że pomoże to niektórym wyjaśnić.
Chciałbym opublikować dokument w ngHref, ale nie mogę z powodu mojej reputacji.
Tak zawsze robię. Działa jak marzenie!
<a href ng-click="do()">Click</a>
Wiele odpowiedzi wydaje się przesadnych. DLA MNIE działa to
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
Potrzebuję obecności wartości atrybutu href do degradacji (gdy js jest wyłączony), więc nie mogę użyć pustego atrybutu href (lub „#”), ale powyższy kod nie działał dla mnie, ponieważ potrzebuję zdarzenia ( e) zmienna. Stworzyłem własną dyrektywę:
angular.module('MyApp').directive('clickPrevent', function() {
return function(scope, element, attrs) {
return element.on('click', function(e) {
return e.preventDefault();
});
};
});
W HTML:
<a data-click-prevent="true" href="/users/sign_up" ng-click="openSignUpModal()">Sign up</a>
Pożyczanie od odpowiedzi Tennisgent. Podoba mi się, że nie musisz tworzyć niestandardowej dyrektywy, aby dodać wszystkie linki. Nie mogłem jednak zmusić go do pracy w IE8. Oto, co w końcu dla mnie zadziałało (używając angular 1.0.6).
Zauważ, że 'bind' pozwala ci używać jqLite dostarczanego przez angular, więc nie musisz owijać pełnego jQuery. Wymagana również metoda 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
, chcę propagacji, ale nie domyślnego zachowania. Ten fragment kodu NIE jest zalecany.
Zetknąłem się z tym samym problemem podczas używania kotwic do rozwijania kątowego paska startowego. Jedynym rozwiązaniem, które zauważyłem, że uniknęło niepożądanych efektów ubocznych (tj. Rozwijanie się nie zamyka z powodu użycia funkcji preventDefault ()), było zastosowanie następujących czynności:
<a href="javascript:;" ng-click="do()">Click</a>
jeśli nigdy nie chcesz iść do href ... powinieneś zmienić swój znacznik i użyć przycisku, a nie tagu kotwicy, ponieważ semantycznie nie jest to kotwica ani link. Odwrotnie, jeśli masz przycisk, który wykonuje pewne kontrole, a następnie przekierowuje, powinien to być link / tag zakotwiczenia, a nie przycisk ... do celów SEO, a także do testowania [wstaw tutaj pakiet testowy].
dla linków, które chcesz tylko warunkowo przekierować, takich jak monit o zapisanie zmian lub potwierdzenie stanu nieczystości ... powinieneś użyć ng-click = "someFunction ($ event)", a w someFunction w swojej walidacjiError zapobiegaj domyślnej i stopPropagacji.
również dlatego, że możesz, nie znaczy, że powinieneś . javascript: void (0) działał dobrze w ciągu dnia ... ale z powodu nikczemnych hakerów / crackerów przeglądarki oznaczają aplikacje / witryny, które używają javascript w href ... nie widzę powodu, aby unikać tego typu ..
jest rok 2016, ponieważ 2010 nie powinien być nigdzie powodem do używania linków, które działają jak przyciski ... jeśli nadal musisz obsługiwać IE8, a poniżej musisz ponownie ocenić swoje miejsce prowadzenia działalności.
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
To, co powinieneś zrobić, to href
całkowicie pominąć atrybut.
Jeśli spojrzeć na kod źródłowy do a
dyrektywy element (który jest częścią kątowego rdzenia), stwierdza się na linii 29 - 31:
if (!element.attr(href)) {
event.preventDefault();
}
Co oznacza, że Angular już rozwiązuje problem linków bez href. Jedyny problem, który nadal masz, to problem z css. Nadal możesz zastosować styl wskaźnika do kotwic, które mają kliknięcia ng, np .:
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
Możesz nawet zwiększyć dostępność witryny, zaznaczając prawdziwe linki subtelną, inną stylizacją niż linki wykonujące funkcje.
Miłego kodowania!
Możesz wyłączyć przekierowanie adresu URL wewnątrz Html5Mode $ location, aby osiągnąć cel. Możesz go zdefiniować w określonym kontrolerze używanym dla strony. Coś takiego:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
Jeśli używasz Angulara 8 lub więcej, możesz utworzyć dyrektywę:
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();
}
}
Na tagu zakotwiczonym w komponencie możesz go połączyć w następujący sposób:
<a ngbDropdownToggle preventDefault class="nav-link dropdown-toggle" href="#" aria-expanded="false" aria-haspopup="true" id="nav-dropdown-2">Pages</a>
Moduł aplikacji powinien mieć deklarację:
import { PreventDefaultDirective } from './shared/directives/preventdefault.directive';
@NgModule({
declarations: [
AppComponent,
PreventDefaultDirective
Alternatywą może być:
<span ng-click="do()">Click</span>
span
do celów klikania. Po prostu skorzystaj z odpowiedzi @ tennisgent - kotwice href
niezdefiniowane.
href
.