Disons que j'ai une balise d'ancrage telle que
<a href="#" ng-click="do()">Click</a>
Comment puis-je empêcher le navigateur de naviguer vers # dans AngularJS ?
href=''
pour garder le comportement du pointeur de la souris.
Disons que j'ai une balise d'ancrage telle que
<a href="#" ng-click="do()">Click</a>
Comment puis-je empêcher le navigateur de naviguer vers # dans AngularJS ?
href=''
pour garder le comportement du pointeur de la souris.
Réponses:
MISE À JOUR : J'ai depuis changé d'avis sur cette solution. Après plus de développement et de temps passé à travailler sur cela, je pense qu'une meilleure solution à ce problème est de procéder comme suit:
<a ng-click="myFunction()">Click Here</a>
Et puis mettez css
à jour votre pour avoir une règle supplémentaire:
a[ng-click]{
cursor: pointer;
}
C'est beaucoup plus simple et offre exactement la même fonctionnalité et est beaucoup plus efficace. J'espère que cela pourrait être utile à toute personne cherchant cette solution à l'avenir.
Ce qui suit est ma solution précédente, que je laisse ici juste à des fins héritées:
Si vous rencontrez souvent ce problème, une simple directive qui permettrait de résoudre ce problème est la suivante:
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();
});
}
}
};
});
Il vérifie toutes les balises d'ancrage ( <a></a>
) pour voir si leur href
attribut est soit une chaîne vide ( ""
) soit un hachage ( '#'
) ou s'il y a une ng-click
affectation. S'il trouve l'une de ces conditions, il intercepte l'événement et empêche le comportement par défaut.
Le seul inconvénient est qu'il exécute cette directive pour toutes les balises d'ancrage. Donc, si vous avez beaucoup de balises d'ancrage sur la page et que vous ne souhaitez empêcher le comportement par défaut que pour un petit nombre d'entre elles, cette directive n'est pas très efficace. Cependant, je le veux presque toujours preventDefault
, donc j'utilise cette directive partout dans mes applications AngularJS.
href
attribut vide a un comportement variable dans différents navigateurs. Bien que je convienne que c'est de loin la solution la plus propre et la plus efficace, elle a quelques problèmes entre les navigateurs. L'utilisation de l'approche directive permet au navigateur de gérer la <a>
balise comme il le ferait normalement, tout en obtenant à l'OP la réponse qu'il recherchait.
Selon la documentation de ngHref, vous devriez pouvoir laisser le href ou faire 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 />
Vous pouvez passer l'objet $ event à votre méthode et l'appeler $event.preventDefault()
afin que le traitement par défaut ne se produise pas:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
$event.preventDefault()
... la taxe IE.
ng-click="do(); $event.preventDefault()
par exemple ... bien que ce ne soit pas nécessaire car la réponse de @ Chris ci-dessous est la bonne. Cela pourrait aider les gens dans des situations où ils ont imbriqué ngClicks et qu'ils souhaitent appeler $event.stopPropagation()
, cependant.
Je préfère utiliser des directives pour ce genre de chose. Voici un exemple
<a href="#" ng-click="do()" eat-click>Click Me</a>
Et le code de directive pour eat-click
:
module.directive('eatClick', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
event.preventDefault();
});
}
})
Vous pouvez maintenant ajouter l' eat-click
attribut à n'importe quel élément et il sera preventDefault()
automatiquement édité.
Avantages:
$event
objet laid dans votre do()
fonction.$event
objetError: $ is not defined
. Qu'est-ce que je rate?
angular.element(element).bind('click', function(event){...});
. Ça a marché. Ref: jQLite
Bien que Renaud ait donné une excellente solution
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
J'ai personnellement trouvé que vous avez également besoin de $ event.stopPropagation () dans certains cas pour éviter certains des effets secondaires
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
sera ma solution
ng-click="$event.preventDefault()"
La solution la plus simple que j'ai trouvée est celle-ci:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Donc, en lisant ces réponses, @Chris a toujours la réponse la plus "correcte", je suppose, mais il a un problème, il n'affiche pas le "pointeur" ....
Voici donc deux façons de résoudre ce problème sans avoir besoin d'ajouter un curseur: style de pointeur:
Utilisez javascript:void(0)
au lieu de #
:
<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
À utiliser $event.preventDefault()
dans la ng-click
directive (pour ne pas joncher votre contrôleur avec des références DOM):
<a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
Personnellement, je préfère le premier au second. javascript:void(0)
a d'autres avantages qui sont discutés ici . Il y a également une discussion sur le «JavaScript discret» dans ce lien qui est effroyablement récent et ne s'applique pas nécessairement directement à une application angulaire.
javascript:;
Vous pouvez faire comme suit
1.Retirer l' href
attribut de la a
balise anchor ( )
2.Réglez le curseur du pointeur en CSS sur les éléments de clic
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
HTML
ici pure angularjs: près de la fonction ng-click, vous pouvez écrire la fonction preventDefault () en séparant le point-virgule
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">Click me</a>
JS
$scope.do = function() {
alert("do here anything..");
}
(ou)
vous pouvez procéder de cette façon, cela est déjà discuté ici.
HTML
<a href="#" ng-click="do()">Click me</a>
JS
$scope.do = function(event) {
event.preventDefault();
event.stopPropagation()
}
Puisque vous créez une application Web, pourquoi avez-vous besoin de liens?
Échangez vos ancres contre des boutons!
<button ng-click="do()"></button>
Le moyen le plus sûr d'éviter les événements sur un href serait de le définir comme
<a href="javascript:void(0)" ....>
J'irais avec:
<a ng-click="do()">Click</a>
L'ensemble de cette chose empêchant le défaut m'a dérouté, j'ai donc créé un JSFiddle pour illustrer quand et où Angular empêche le défaut .
Le JSFiddle utilise la directive a d'Angular - il devrait donc être EXACTEMENT le même. Vous pouvez voir le code source ici: un code source de balise
J'espère que cela aidera la clarification pour certains.
J'aurais aimé poster le doc sur ngHref mais je ne peux pas à cause de ma réputation.
C'est ce que je fais toujours. Fonctionne comme un charme!
<a href ng-click="do()">Click</a>
Beaucoup de réponses semblent exagérées. POUR MOI, ça marche
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
J'ai besoin d'une présence de la valeur de l'attribut href pour la dégradation (lorsque js est désactivé), donc je ne peux pas utiliser l'attribut href vide (ou "#"), mais le code ci-dessus n'a pas fonctionné pour moi, car j'ai besoin d'un événement ( e) variable. J'ai créé ma propre directive:
angular.module('MyApp').directive('clickPrevent', function() {
return function(scope, element, attrs) {
return element.on('click', function(e) {
return e.preventDefault();
});
};
});
En HTML:
<a data-click-prevent="true" href="/users/sign_up" ng-click="openSignUpModal()">Sign up</a>
Empruntant à la réponse de tennisgent. J'aime que vous n'ayez pas à créer une directive personnalisée à ajouter sur tous les liens. Cependant, je n'ai pas pu faire fonctionner son IE8. Voici ce qui a finalement fonctionné pour moi (en utilisant angulaire 1.0.6).
Notez que 'bind' vous permet d'utiliser jqLite fourni par angular donc pas besoin de boucler avec jQuery complet. Également requis la méthode 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
, je veux la propagation mais pas le comportement par défaut. Cet extrait n'est PAS recommandé.
J'ai rencontré ce même problème lors de l'utilisation d'ancres pour une liste déroulante de bootstrap angulaire. La seule solution que j'ai trouvée qui a évité les effets secondaires indésirables (c'est-à-dire la liste déroulante ne se fermant pas en raison de l'utilisation de preventDefault ()) était d'utiliser ce qui suit:
<a href="javascript:;" ng-click="do()">Click</a>
si vous ne voulez jamais aller à href ... vous devez changer votre balisage et utiliser un bouton et non une balise d'ancrage car sémantiquement ce n'est pas une ancre ou un lien. Inversement, si vous avez un bouton qui vérifie puis redirige, ce devrait être un lien / une balise d'ancrage et non un bouton ... à des fins de référencement ainsi que de test [insérer la suite de tests ici].
pour les liens que vous souhaitez uniquement rediriger de manière conditionnelle comme l'invite à enregistrer les modifications ou à reconnaître l'état sale ... vous devez utiliser ng-click = "someFunction ($ event)" et dans someFunction sur votre validationError preventDefault et ou stopPropagation.
aussi parce que vous pouvez ne signifie pas que vous devriez . javascript: void (0) a bien fonctionné à l'époque ... mais à cause des hackers / crackers néfastes, les navigateurs signalent les applications / sites qui utilisent javascript dans un href ... ne voyez aucune raison de ducktype ci-dessus ..
c'est 2016 depuis 2010 ne devrait être aucune raison d'utiliser des liens qui agissent comme des boutons ... si vous devez toujours prendre en charge IE8 et ci-dessous, vous devez réévaluer votre établissement.
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
Ce que vous devez faire, c'est supprimer href
complètement l' attribut.
Si vous regardez le code source de la a
directive élément (qui fait partie du noyau angulaire), il indique à la ligne 29 - 31:
if (!element.attr(href)) {
event.preventDefault();
}
Ce qui signifie qu'Angular résout déjà le problème des liens sans href. Le seul problème que vous avez toujours est le problème css. Vous pouvez toujours appliquer le style de pointeur aux ancres avec ng-clics, par exemple:
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
Ainsi, vous pouvez même rendre votre site plus accessible en marquant de vrais liens avec un style subtil et différent, puis des liens qui remplissent des fonctions.
Bon codage!
Vous pouvez désactiver la redirection d'URL dans le Html5Mode de $ location pour atteindre l'objectif. Vous pouvez le définir à l'intérieur du contrôleur spécifique utilisé pour la page. Quelque chose comme ça:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
Si vous utilisez Angular 8 ou plus, vous pouvez créer une directive:
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();
}
}
Sur votre balise d'ancrage sur le composant, vous pouvez le câbler comme ceci:
<a ngbDropdownToggle preventDefault class="nav-link dropdown-toggle" href="#" aria-expanded="false" aria-haspopup="true" id="nav-dropdown-2">Pages</a>
Le module d'application doit avoir sa déclaration:
import { PreventDefaultDirective } from './shared/directives/preventdefault.directive';
@NgModule({
declarations: [
AppComponent,
PreventDefaultDirective
Une alternative pourrait être:
<span ng-click="do()">Click</span>
span
pour cliquer. Allez juste pour la réponse de @ tennisgent - ancres sans href
défini.
href
.