提问



让我们说我有一个锚标签,如


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


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

最佳参考


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


<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属性是空字符串("")还是哈希('#')或者有[['#') 42]]任务。如果它发现任何这些条件,它会捕获事件并阻止默认行为。


唯一的缺点是它为所有锚标签运行此指令。因此,如果你在页面上有很多锚标记而你只想防止少数锚标记的默认行为,那么这个指令不是很有效。但是,我几乎总是想要preventDefault,所以我在AngularJS应用程序中使用了这个指令。

其它参考1


根据ngHref的文档,你应该能够离开href或做href =。[60]


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

其它参考2


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


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

// then in your controller.do($event) method
$event.preventDefault()

其它参考3


我更喜欢使用指令来做这种事情。这是一个例子


<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()


优点:



  1. 您不必将丑陋的$event对象传递到do()函数中。

  2. 您的控制器更易于单元测试,因为它不需要存根$event对象


其它参考4


虽然雷诺给出了很好的解决方案


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


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


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


将是我的解决方案

其它参考5


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

其它参考6


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


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

其它参考7


因此,通过这些答案,@ Chris仍然有最正确的答案,我想,但它有一个问题,它没有显示指针....


所以这里有两种解决这个问题的方法,无需添加游标:指针样式:



  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,这是一个令人恐惧的最近,并不一定直接适用于角度应用。

其它参考8


你可以这样做


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


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


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

其它参考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()
}

其它参考10


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


将锚点交换到按钮!


<button ng-click="do()"></button>

其它参考11


如果仍然相关:


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

...

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

...

其它参考12


尝试这个我可以看到的选项尚未列在上面:


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

其它参考13


我会选择:


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



  • 因为根据文档,您应该能够离开href,然后Angular将为您处理防止默认值!



整个这个防止默认的事情让我感到困惑,所以我创建了一个JSFiddle
这里说明了Angular阻止默认的时间和地点
[62]


JSFiddle使用Angular的指令 - 所以它应该完全相同。你可以在这里看到源代码:标签源代码[63]


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


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

其它参考14


这就是我一直以来所做的。奇迹般有效!


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

其它参考15


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


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

其它参考16


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


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

其它参考17


很多答案似乎有点矫枉过正。对我来说,这是有效的


 <a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>

其它参考18


我需要存在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>

其它参考19


借用网球的答案。我喜欢你不必创建一个自定义指令来添加所有链接。但是,我无法让他在IE8中工作。这是最终为我工作的(使用角度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();
                    }
                })
            }
        };
    }
])

其它参考20


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


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

其它参考21


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


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


只是因为你不能意味着你应该 .javascript:void(0)在当天运作良好...但是因为邪恶的黑客/黑客浏览器标记使用javascript的应用/网站在一个href ...看到没有理由鸭型以上..


它是2016年自2010年以来应该没有任何理由使用像按钮一样的链接...如果你仍然需要支持IE8及以下,你需要重新评估你的营业地点。

其它参考22


/* NG CLICK PREVENT DEFAULT */

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

其它参考23


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


如果你看一下a元素指令的源代码(它是Angular核心的一部分),它在第29-31行说明:[64]


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


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




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



另一种选择可能是:


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