私がアンカータグを持っているとしましょう
<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 を省略したり、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
。何が欠けていますか?
ルノーは素晴らしい解決策を提供しましたが
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
個人的には、副作用を回避するために、場合によっては$ event.stopPropagation()も必要であることがわかりました
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
私の解決策になります
ng-click="$event.preventDefault()"
私が見つけた最も簡単な解決策はこれです:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
したがって、これらの回答を読んでも、@ Chrisはまだ「正しい」回答を持っていると思いますが、問題が1つあり、「ポインタ」が表示されません...
したがって、cursor:pointerスタイルを追加することなく、この問題を解決する2つの方法があります。
の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>
私は一緒に行きます:
<a ng-click="do()">Click</a>
これがデフォルトを防ぐことは私を混乱させてきたので 、Angularがいつデフォルトを妨げているのかを示すJSFiddleを作成しました。
JSFiddleはAngularのディレクティブを使用しているため、まったく同じである必要があります。ここでソースコードを見ることができます:タグのソースコード
これが一部の説明に役立つことを願っています。
ドキュメントをngHrefに投稿したかったのですが、自分の評判が悪かったのでできません。
(jsがオフになっている場合)低下のためにhref属性の値の存在が必要なため、空の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で彼を働かせることはできませんでした。これが私にとって最終的に機能したものです(angular 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)"およびsomeFunctionでvalidationError preventDefaultおよび/またはstopPropagationを使用する必要があります。
また、あなたができるからといって。javascript:void(0)はその日はうまく機能しました...しかし、悪意のあるハッカー/クラッカーのブラウザが、href内でjavascriptを使用するアプリ/サイトにフラグを立てるので、上記のducktypeの理由はありません。
ボタンのように機能するリンクを使用する理由は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
属性を完全に省略することです。
elementディレクティブ(Angularコアの一部)のソースコードを見ると、29〜31行目に次のように記述されていa
ます。
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
クリック目的でaを悪用するのは恐ろしい習慣です。@tennisgentの答えにただ進んでください- href
定義されていないアンカーです。
href
。