如何防止锚标签的默认?

问题描述 投票:337回答:26

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

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

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

angularjs preventdefault
26个回答
253
投票

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

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


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

6
投票

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

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

5
投票

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

将锚点交换到按钮!

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

5
投票

如果仍然相关:

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

...

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

...

5
投票

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

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

4
投票

我会选择:

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

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

JSFiddle正在使用Angular的一个指令 - 所以它应该完全相同。你可以在这里看到源代码:a tag source code

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

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


4
投票

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

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

3
投票

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

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

3
投票

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

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

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>

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
投票

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

1
投票

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

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

1
投票

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

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

也只是因为你不能意味着你应该。 javascript:void(0)在当天运作良好...但由于邪恶的黑客/黑客浏览器标记在href中使用javascript的应用程序/网站...看不出上面的ducktype的理由..

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


0
投票
/* NG CLICK PREVENT DEFAULT */

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

0
投票

你应该做什么,完全省略href属性。

如果你查看source codea元素指令(它是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;
}

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

快乐的编码!


0
投票

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

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

-2
投票

另一种选择可能是:

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

235
投票

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

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

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

109
投票

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

<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对象

52
投票

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

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

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

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

将是我的解决方案


33
投票
ng-click="$event.preventDefault()"

33
投票

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

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

10
投票

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

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

  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)有其他好处,discussed here。在该链接中还讨论了“不显眼的JavaScript”,这是最近可怕的,并不一定直接适用于角度应用。


9
投票

你可以这样做

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

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

 [ng-click],
 [data-ng-click],
 [x-ng-click] {
     cursor: pointer;
 }
© www.soinside.com 2019 - 2024. All rights reserved.