假设我有一个锚标记,例如
<a href="#" ng-click="do()">Click</a>
如何防止浏览器导航到AngularJS中的#?
href=''
用来保持鼠标指针行为的。
假设我有一个锚标记,例如
<a href="#" ng-click="do()">Click</a>
如何防止浏览器导航到AngularJS中的#?
href=''
用来保持鼠标指针行为的。
Answers:
更新:此后,我改变了主意。经过更多的开发和花时间进行此工作之后,我相信针对此问题的更好解决方案是执行以下操作:
<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应用程序中全部使用了此指令。
href
属性在不同的浏览器中具有不同的行为。尽管我同意这是迄今为止最干净,最有效的解决方案,但确实存在一些跨浏览器的问题。使用指令方法可以使浏览器<a>
按正常方式处理标签,但仍可以让OP获得他们正在寻找的答案。
根据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 />
您可以将$ event对象传递给您的方法,然后对其进行调用$event.preventDefault()
,这样就不会发生默认处理:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
$event.preventDefault()
... IE税。
ng-click="do(); $event.preventDefault()
例如,...,但这不是必需的,因为下面@Chris的答案是正确的。但是,这在嵌套ngClicks并希望致电的情况下可能对人们有所帮助$event.stopPropagation()
。
我更喜欢对此类事情使用指令。这是一个例子
<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
对象Error: $ is not defined
。我想念什么?
angular.element(element).bind('click', function(event){...});
。有效。参考:jQLite
尽管Renaud提供了很好的解决方案
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
我个人发现在某些情况下,您还需要$ event.stopPropagation()以避免某些副作用
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
将是我的解决方案
我找到的最简单的解决方案是:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
因此,通读这些答案,我想@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)
还有其他好处在这里讨论。在该链接中还讨论了“不打扰的JavaScript”,这是令人恐惧的最新消息,不一定直接应用于有角度的应用程序。
javascript:;
的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()
}
既然您正在制作一个Web应用程序,为什么需要链接?
交换锚点到按钮!
<button ng-click="do()"></button>
我需要存在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>
从网球场的答案中借来的。我喜欢您不必创建自定义指令来添加所有链接。但是,我无法让他在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();
}
})
}
};
}
])
dropdown
,我希望传播而不是默认行为。不建议使用此代码段。
如果您永远不想访问href ...,则应更改标记并使用按钮而不是锚标记,因为从语义上讲它不是锚或链接。相反,如果您有一个进行一些检查然后重定向的按钮,则应该是一个链接/锚标记,而不是一个按钮...出于SEO的目的以及测试[在此处插入测试套件]。
对于只希望有条件重定向的链接,例如提示保存更改或确认脏状态...,应使用ng-click =“ someFunction($ event)”并在validateError的someFunction中的preventDefault和StopPropagation上使用。
也仅仅因为你能做并不意味着你应该。javascript:void(0)在一天中运作良好...但是由于骇客/骇客浏览器在href内标记了使用javascript的应用/网站,因此没有理由在上面使用ducktype。
从2010年开始,应该是2016年。如果您仍然必须支持IE8,则您应该重新评估您的营业地点。自2010年以来,我们就无处使用按钮之类的链接了。
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
您应该做的是href
完全忽略属性。
如果你看一下源代码的a
元素指令(这是方芯的一部分),它规定在第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;
}
因此,您甚至可以通过标记实际的链接,使它们具有更细微的样式,然后再执行功能,从而使您的网站更易于访问。
编码愉快!
如果您使用的是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
一种替代方法可能是:
<span ng-click="do()">Click</span>
span
进行点击是一种可怕的做法。只是去@tennisgent的答案-锚没有href
定义。
href
。