如何防止锚标签的默认?
比方说,我有一个锚标记,如
<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()
。
优点:
- 你不必把丑陋的
$event
对象传递给你的do()
函数。 - 您的控制器是更多的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:
-
使用
javascript:void(0)
而不是#
:<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
-
在
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提供的jqLite,所以不需要用完整的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>