假设我有一个锚标记,例如
<a href="#" ng-click="do()">Click</a>
如何阻止浏览器导航到 AngularJS 中的#?
答案 0 :(得分:319)
根据docs for 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 />
答案 1 :(得分:256)
更新:我已经改变了对这个解决方案的看法。经过更多的开发和时间花在这上面,我相信这个问题的更好的解决方案是做以下事情:
<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
如果它发现任何这些条件,它会捕获事件并阻止默认行为。
唯一的缺点是它为所有锚标签运行此指令。因此,如果页面上有很多锚标记,并且您只想阻止少数锚标记的默认行为,则该指令效率不高。但是,我几乎总是想要{{1}},所以我在AngularJS应用程序中使用了这个指令。
答案 2 :(得分:235)
您可以将$ event对象传递给您的方法,并在其上调用$event.preventDefault()
,以便不会发生默认处理:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
答案 3 :(得分:110)
我更喜欢使用指令来做这种事情。这是一个例子
<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
对象答案 4 :(得分:52)
虽然雷诺给出了一个很好的解决方案
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
我个人发现在某些情况下你还需要$ event.stopPropagation()以避免一些副作用
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
将是我的解决方案
答案 5 :(得分:33)
我找到的最简单的解决方案是:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
答案 6 :(得分:33)
ng-click="$event.preventDefault()"
答案 7 :(得分:10)
通过阅读这些答案,我认为@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)
还有discussed here的其他好处。在该链接中还讨论了“不显眼的JavaScript”,这是一个令人恐惧的最近,并不一定直接适用于角度应用。
答案 8 :(得分:9)
您可以执行以下操作
1.从锚点(href
)标记
a
属性
2.将css中的指针光标设置为ng点击元素
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
答案 9 :(得分:8)
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()
}
答案 10 :(得分:6)
尝试此选项,我可以看到上面尚未列出:
<a href="" ng-click="do()">Click</a>
答案 11 :(得分:5)
由于您正在制作网络应用,为什么还需要链接?
将你的锚点交换到按钮!
<button ng-click="do()"></button>
答案 12 :(得分:5)
如果仍然相关:
<a ng-click="unselect($event)" />
...
scope.unselect = function( event ) {
event.preventDefault();
event.stopPropagation();
}
...
答案 13 :(得分:5)
避免href事件的最安全方法是将其定义为
<a href="javascript:void(0)" ....>
答案 14 :(得分:4)
我会选择:
<a ng-click="do()">Click</a>
整个这个防止默认的事情让我感到困惑,所以我创建了一个JSFiddle 这里说明了Angular阻止默认的时间和地点。
JSFiddle正在使用Angular的一个指令 - 所以它应该完全相同。您可以在此处查看源代码:a tag source code
我希望这有助于澄清一些人。
我本来希望将文档发布到ngHref,但由于我的声誉,我不能。
答案 15 :(得分:4)
这就是我一直以来所做的。像魅力一样工作!
<a href ng-click="do()">Click</a>
答案 16 :(得分:3)
许多答案似乎有点矫枉过正。对我而言,这是有效的
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
答案 17 :(得分:3)
或者,如果您需要内联,那么您可以这样做:
<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>
答案 18 :(得分:1)
借用网球的回答。我喜欢你不必创建一个自定义指令来添加所有链接。但是,我无法让他在IE8中工作。这是最终为我工作的(使用角度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();
}
})
}
};
}
])
答案 19 :(得分:1)
如果你不想去href ...你应该改变你的标记并使用按钮而不是锚标记,因为从语义上来说它不是锚或链接。反过来,如果你有一个按钮进行一些检查,然后重定向它应该是一个链接/锚标签,而不是一个按钮...用于搜索引擎优化目的以及测试[在这里插入测试套件]。
对于您只想有条件地重定向的链接,比如提示保存更改,或者确认脏状态......您应该使用ng-click =&#34; someFunction($ event)&#34;在validationError上的someFunction中,使用preventDefault和/或stopPropagation。
也只是因为你不能表示你应该。 javascript:void(0)在当天工作得很好...但是由于邪恶的黑客/黑客浏览器标记在href中使用javascript的应用程序/网站...看不出上面的鸭子类型..
它自2016年以来2016年应该没有任何理由可以使用类似按钮的链接...如果您仍然需要支持IE8及以下,则需要重新评估您的营业地点。
答案 20 :(得分:1)
当使用锚点进行角度引导下拉时,我遇到了同样的问题。我发现避免不必要的副作用的唯一解决方案(即因使用preventDefault()导致的下拉不关闭)是使用以下内容:
<a href="javascript:;" ng-click="do()">Click</a>
答案 21 :(得分:1)
我需要存在href属性的降级值(当js关闭时),所以我不能使用空的href属性(或“#”),但上面的代码对我不起作用,因为我需要事件(e)变量。我创建了自己的指令:
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>
答案 22 :(得分:0)
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
答案 23 :(得分:0)
您应该做的是完全省略href
属性。
如果你查看a
元素指令的source code(它是Angular核心的一部分),它会在第29-31行说明:
if (!element.attr(href)) {
event.preventDefault();
}
这意味着Angular已经解决了没有href的链接问题。你仍然唯一的问题是css问题。您仍然可以将指针样式应用于具有ng-clicks的锚点,例如:
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
因此,您甚至可以通过使用细微的,不同的样式标记真实链接以及执行功能的链接来使您的网站更易于访问。
快乐的编码!
答案 24 :(得分:0)
您可以在$ location的Html5Mode中禁用网址重定向以实现目标。您可以在用于页面的特定控制器内定义它。 像这样:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
答案 25 :(得分:0)
如果您使用的是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
答案 26 :(得分:0)
就我而言 Angular: 10 - 这样做
ubuntu
更新:此方法将重新加载解析器。谢谢@Meeker
答案 27 :(得分:-2)
替代方案可能是:
<span ng-click="do()">Click</span>