348

假设我有一个锚标签,例如

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

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

4

28 回答 28

322

根据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 />
于 2012-07-26T15:37:30.483 回答
261

更新:我已经改变了对这个解决方案的想法。经过更多的开发和时间,我相信解决这个问题的更好方法是执行以下操作:

<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,所以我在我的 AngularJS 应用程序中使用了这个指令。

于 2013-08-01T16:21:36.893 回答
243

您可以将 $event 对象传递给您的方法,并$event.preventDefault()对其进行调用,这样就不会发生默认处理:

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

// then in your controller.do($event) method
$event.preventDefault()
于 2012-06-07T12:20:39.830 回答
111

我更喜欢对这类事情使用指令。这是一个例子

<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()自动获得 'ed。

好处:

  1. 您不必将丑陋的$event对象传递给您的do()函数。
  2. 您的控制器更易于单元测试,因为它不需要存根$event对象
于 2013-01-04T22:13:35.293 回答
56

虽然 Renaud 给出了一个很好的解决方案

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

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

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

将是我的解决方案

于 2014-05-26T19:18:30.310 回答
35

我找到的最简单的解决方案是这个:

<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
于 2013-02-27T02:33:36.617 回答
34
ng-click="$event.preventDefault()"
于 2013-10-08T06:02:58.070 回答
11

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

所以这里有两种方法可以解决这个问题,而无需添加 cursor:pointer 样式:

  1. 使用javascript:void(0)代替#

    <a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
    
  2. $event.preventDefault()在指令中使用ng-click(这样您就不会将控制器与 DOM 相关的引用混为一谈):

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

就个人而言,我更喜欢前者而不是后者。javascript:void(0)具有此处讨论的其他好处。该链接中还讨论了“不显眼的 JavaScript”,这是最近令人恐惧的,不一定直接适用于 Angular 应用程序。

于 2014-03-27T01:41:35.923 回答
10

您可以执行以下操作

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

2.将css中的指针光标设置为ng click元素

 [ng-click],
 [data-ng-click],
 [x-ng-click] {
     cursor: pointer;
 }
于 2013-12-20T13:33:54.630 回答
9

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()
}
于 2015-03-17T11:02:07.040 回答
7

既然您正在制作网络应用程序,为什么需要链接?

将您的锚点换成按钮!

<button ng-click="do()"></button>
于 2013-09-18T11:20:55.853 回答
7

试试这个我可以看到上面还没有列出的选项:

<a href="" ng-click="do()">Click</a>
于 2015-11-03T14:09:10.057 回答
6

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

<a href="javascript:void(0)" ....>
于 2013-03-28T16:05:45.330 回答
6

如果仍然相关:

<a ng-click="unselect($event)" />

...

scope.unselect = function( event ) {
 event.preventDefault();
 event.stopPropagation();
}

...
于 2014-02-05T16:42:59.953 回答
5

我会去:

<a ng-click="do()">Click</a>
  • 因为根据文档,您应该能够离开 href,然后 Angular 将为您处理阻止默认值!

整个这个防止默认的事情一直让我感到困惑,所以我在那里创建了一个JSFiddle 来 说明 Angular 何时何地阻止 default

JSFiddle 使用 Angular 的 a 指令——所以它应该完全相同。你可以在这里看到源代码:一个标签源代码

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

我本来希望将文档发布到 ngHref,但由于我的声誉,我不能。

于 2014-01-15T07:57:03.487 回答
5

这就是我一直在做的事情。奇迹般有效!

<a href ng-click="do()">Click</a>
于 2014-12-18T17:40:58.227 回答
4

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

<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>
于 2014-06-25T16:17:04.787 回答
4

很多答案似乎是矫枉过正。对我来说,这行得通

 <a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
于 2017-07-10T20:55:10.253 回答
2

我需要存在 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>
于 2013-09-16T15:23:54.037 回答
2

借用tenensgent的答案。我喜欢您不必创建自定义指令来添加所有链接。但是,我无法让他在 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();
                    }
                })
            }
        };
    }
])
于 2013-09-19T22:31:25.020 回答
2

在使用锚点进行角度引导下拉时,我遇到了同样的问题。我发现避免不必要的副作用的唯一解决方案(即,由于使用 preventDefault() 而没有关闭下拉菜单)是使用以下内容:

 <a href="javascript:;" ng-click="do()">Click</a>
于 2014-11-19T20:42:06.000 回答
2

如果你不想去href...你应该改变你的标记并使用一个按钮而不是一个锚标记,因为从语义上它不是一个锚或链接。相反,如果您有一个按钮进行一些检查然后重定向它应该是一个链接/锚标记而不是一个按钮......用于搜索引擎优化目的以及测试[在此处插入测试套件]。

对于您只想有条件地重定向的链接,例如提示保存更改或确认脏状态...您应该使用 ng-click="someFunction($event)" 并在您的validationError preventDefault 和/或stopPropagation 的someFunction 中。

只是因为你可以并不意味着你应该。javascript:void(0) 在过去运行良好...但是由于邪恶的黑客/破解者浏览器标记了在 href 中使用 javascript 的应用程序/站点...请参阅上面没有理由鸭式..

现在是 2016 年,因为 2010 年应该没有理由在任何地方使用像按钮一样的链接......如果您仍然需要支持 IE8 及以下版本,您需要重新评估您的营业地点。

于 2016-01-05T04:25:37.550 回答
1
/* NG CLICK PREVENT DEFAULT */

app.directive('ngClick', function () {
    return {
        link: function (scope, element, attributes) {
            element.click(function (event) {
                event.preventDefault();
                event.stopPropagation();
            });
        }
    };
});
于 2015-03-31T21:30:04.437 回答
1

您应该做的是href完全省略该属性。

如果您查看element 指令(它是 Angular 核心的一部分)的源代码,它在第 29 - 31 行声明:a

if (!element.attr(href)) {
    event.preventDefault();
}

这意味着 Angular 已经在解决没有 href 的链接问题。您仍然存在的唯一问题是css问题。您仍然可以将指针样式应​​用于具有 ng-click 的锚点,例如:

a[ng-click] {
    /* Styles for anchors without href but WITH ng-click */
    cursor: pointer;
}

因此,您甚至可以通过使用与执行功能的链接不同的微妙样式来标记真实链接,从而使您的网站更易于访问。

快乐编码!

于 2016-04-13T11:58:29.627 回答
1

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

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

于 2017-08-30T13:39:15.913 回答
1

如果您使用的是 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>

App Module 应该有它的声明:

import { PreventDefaultDirective } from './shared/directives/preventdefault.directive';


@NgModule({
  declarations: [
    AppComponent,
    PreventDefaultDirective
于 2019-11-20T11:33:26.853 回答
0

在我的情况下 Angular: 10 - 工作这个

  <a [routerLink]="" (click)="myFunc()"> Click me </a>

更新:此方法将重新加载解析器。谢谢@Meeker

于 2021-03-03T12:45:24.217 回答
-1

另一种选择可能是:

<span ng-click="do()">Click</span>
于 2013-05-10T21:11:32.730 回答