다음과 같은 앵커 태그가 있다고 가정 해 봅시다.
<a href="#" ng-click="do()">Click</a>
AngularJS 에서 브라우저가 #으로 이동하지 못하게하려면 어떻게 해야합니까?
href=''
는 마우스 포인터 동작을 유지하기 위해 사용 하는 것이 아닙니다 .
다음과 같은 앵커 태그가 있다고 가정 해 봅시다.
<a href="#" ng-click="do()">Click</a>
AngularJS 에서 브라우저가 #으로 이동하지 못하게하려면 어떻게 해야합니까?
href=''
는 마우스 포인터 동작을 유지하기 위해 사용 하는 것이 아닙니다 .
답변:
업데이트 : 이후이 솔루션에 대한 내 생각이 바뀌 었습니다. 더 많은 개발과 시간을 보낸 후에이 문제에 대한 더 나은 해결책은 다음을 수행하는 것입니다.
<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 또는 do 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.preventDefault()
가 발생하지 않도록 $ event 객체를 메소드에 전달하고 호출 할 수 있습니다.
<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의 답변이 올바른 것이기 때문에 필요하지는 않습니다. $event.stopPropagation()
그러나 ngClick이 중첩되어 있고을 호출하려는 상황에있는 사람들에게 도움이 될 수 있습니다 .
이런 종류의 지시문 을 사용하는 것을 선호합니다 . 여기에 예가 있습니다
<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
ng-click="$event.preventDefault()"
따라서 @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:;
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()
}
웹앱을 제작하고 있는데 왜 링크가 필요합니까?
앵커를 버튼으로 바꾸십시오!
<button ng-click="do()"></button>
나는 함께 갈 것이다 :
<a ng-click="do()">Click</a>
전체적으로이 기본 방지 기능이 혼란 스럽기 때문에 Angular가 기본을 방지하는 시간과 위치를 보여주는 JSFiddle 을 만들었습니다 .
JSFiddle은 Angular의 지시문을 사용하므로 정확히 동일해야합니다. 소스 코드는 여기에서 볼 수 있습니다 : 태그 소스 코드
나는 이것이 일부를 명확히하는 데 도움이되기를 바랍니다.
문서를 ngHref에 게시하고 싶었지만 평판 때문에 할 수 없습니다.
성능 저하에 대한 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>
tennisgent의 답변에서 차용. 모든 링크에 추가하기 위해 사용자 지정 지시문을 만들 필요는 없습니다. 그러나 IE8에서 그의 일을 할 수 없었습니다. 마지막으로 나를 위해 일한 것이 있습니다 (각도 1.0.6 사용).
'바인드'를 사용하면 각도로 제공되는 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)"및 validationError preventDefault 및 / 또는 stopPropagation에 someFunction을 사용해야합니다.
또한 당신이해야한다는 것을 의미 할 수 없기 때문에 . javascript : void (0)는 하루 전에 잘 작동했지만 악의적 인 해커 / 크래커 브라우저로 인해 href 내에서 javascript를 사용하는 앱 / 사이트에 플래그가 지정되었습니다.
2010 년 이후 2016 년 이후로 버튼처럼 작동하는 링크를 사용해야하는 이유는 없습니다. IE8 이하를 계속 지원해야하는 경우 사업장을 다시 평가해야합니다.
/* 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- 클릭이있는 앵커에 포인터 스타일을 적용 할 수 있습니다.
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 's answer- href
정의 되지 않은 앵커로 이동하십시오 .
href
.