假设我有一个锚标记,比如

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

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


当前回答

我在使用锚进行角引导下拉时遇到了同样的问题。我发现唯一的解决方案,避免不必要的副作用(即。因为使用preventDefault())而没有关闭的下拉列表使用以下方法:

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

其他回答

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

根据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 />

尽管雷诺给出了一个很好的解决方案

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

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

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

就是我的解

/* NG CLICK PREVENT DEFAULT */

app.directive('ngClick', function () {
    return {
        link: function (scope, element, attributes) {
            element.click(function (event) {
                event.preventDefault();
                event.stopPropagation();
            });
        }
    };
});

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

<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应用程序中都使用这个指令。