如何防止锚标签的默认?

比方说,我有一个锚标记,如

<a href="#" ng-click="do()">Click</a> 

如何防止浏览器在AngularJS中导航到#号?

更新 :我已经改变了我的想法在这个解决scheme。 经过更多的开发和时间的工作,我相信这个问题的更好的解决scheme是做到以下几点:

 <a ng-click="myFunction()">Click Here</a> 

然后更新你的css有一个额外的规则:

 a[ng-click]{ cursor: pointer; } 

它更简单,并提供完全相同的function,更高效。 希望将来可以帮助其他人查找这个解决scheme。


以下是我以前的解决scheme,我只是为了遗留目的而离开这里:

如果你有这个问题很多,一个简单的指令可以解决这个问题,如下所示:

 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属性是空string( "" )还是哈希( '#' )或是否有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> 

和点击的指令代码:

 module.directive('eatClick', function() { return function(scope, element, attrs) { $(element).click(function(event) { event.preventDefault(); }); } }) 

现在,您可以将eat-click属性添加到任何元素,并自动获取preventDefault()

优点:

  1. 你不必把丑陋的$event对象传递给你的do()函数。
  2. 您的控制器是更多的unit testing,因为它不需要存根$event对象

尽pipe雷诺给出了很好的解决scheme

 <a href="#" ng-click="do(); $event.preventDefault()">Click</a> 

我个人发现你在某些情况下还需要$ event.stopPropagation()来避免一些副作用

 <a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();"> Click</a> 

将是我的解决scheme

 ng-click="$event.preventDefault()" 

我发现的最简单的解决scheme是:

 <a href="#" ng-click="do(); $event.preventDefault()">Click</a> 

所以通过这些答案阅读,@Chris仍然有最“正确的”答案,我想,但它有一个问题,它不显示“指针”….

所以这里有两种方法可以解决这个问题,而不需要添加游标:pointer style:

  1. 使用javascript:void(0)而不是#

     <a href="javascript:void(0)" ng-click="doSomething()">Do Something</a> 
  2. ng-click指令中使用$event.preventDefault() (所以你不要把你的控制器和DOM相关的引用混淆在一起):

     <a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a> 

我个人比较喜欢前者。 javascript:void(0)有其他的好处, 这里讨论 。 在那个令人恐惧的最近的链接中也有关于“不显眼的JavaScript”的讨论,并不一定直接适用于angular度应用。

你可以做如下

1.从anchor( a )标签中删除href属性

2.在css中设置指针光标到ng元素

  [ng-click], [data-ng-click], [x-ng-click] { cursor: pointer; } 

HTML

这里纯粹的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() } 

既然你正在做一个networking应用程序,你为什么需要链接?

交换你的锚到button!

 <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> 
  • 因为根据文档,你应该可以离开的href,然后Angular将处理预防默认为你!

整个这个防止默认的东西一直困扰着我,所以我创build了一个JSFiddle在那里说明何时何地Angular防止默认

JSFiddle正在使用Angular的一个指令 – 所以它应该是完全一样的。 你可以在这里看到源代码: 一个标签源代码

我希望这将有助于澄清一些。

我本来希望把这个文件发布到ngHref,但是我不能因为我的声望。

这是我总是这样做的。 奇迹般有效!

 <a href ng-click="do()">Click</a> 

或者,如果你需要内联,那么你可以这样做:

 <a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a> 

避免href事件的最安全的方法是将其定义为

 <a href="javascript:void(0)" ....> 

我需要一个存在的href属性的值退化(当closuresjs),所以我不能使用空的href属性(或“#”),但上面的代码不适合我,因为我需要一个事件e)variables。 我创build了我自己的指令:

 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> 

从tennisight的答案借用。 我喜欢你不必创build一个自定义指令来添加所有的链接。 但是,我不能让他在IE8上工作。 这是最后为我工作(使用angular度1.0.6)。

注意'bind'允许你使用angular提供的jqLit​​e,所以不需要用完整的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度引导下拉时,我遇到了同样的问题。 我发现唯一的解决scheme,避免不必要的副作用(即下降不closures,因为使用preventDefault())是使用以下内容:

  <a href="javascript:;" ng-click="do()">Click</a> 

如果你永远不想去href …你应该改变你的标记,并使用一个button,而不是一个锚标记,因为在语义上它不是一个锚点或链接。 相反,如果你有一个button,做一些检查,然后redirect它应该是一个链接/锚定标记,而不是一个button…为SEO的目的,以及testing[插入testing套件在这里]。

对于您只希望有条件地redirect的链接,如提示保存更改,或确认脏状态…您应该使用ng-click =“someFunction($ event)”并在您的validationError preventDefault和/或stopPropagation的某些函数中使用。

只是因为你可以不意味着你应该 。 javascript:void(0)在当天工作得很好……但是因为恶意的黑客/cookies浏览器会标记在href中使用javascript的应用程序/网站。

这是2016年以来,从2010年应该是没有任何理由使用链接的行为像button…如果你仍然需要支持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; } 

因此,甚至可以通过标记真实的链接,使用细微的,不同的样式和执行function的链接,使您的网站更易于访问。

快乐的编码!

您可以禁用$ location的Html5Mode内的urlredirect来实现目标。 您可以在用于页面的特定控制器内定义它。 像这样的东西:

 app.config(['$locationProvider', function ($locationProvider) { $locationProvider.html5Mode({ enabled: true, rewriteLinks: false, requireBase: false }); }]); 

另一种可能是:

 <span ng-click="do()">Click</span>