次のようなアンカータグがあるとしましょう。
<a href="#" ng-click="do()">Click</a>
ブラウザが#in AngularJS に移動しないようにするにはどうすればよいですか。
_ update _ :私はこの解決策について私の考えを変えました。もっと多くの開発とこれに取り組む時間を費やした後、私はこの問題に対するより良い解決策が以下をすることであると信じます:
<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アプリケーションで使用しています。
NgHrefの docsによると あなたは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()
私は ディレクティブ を使うのが好きです。これが例です
<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
オブジェクトをスタブアウトする必要がないので、あなたのコントローラはより単体テスト可能です。ルノーは素晴らしい解決策を提供したが
<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>
それで、これらの答えを読んで、@クリスはまだ最も「正しい」答えを持っている、と私は思いますが、それは一つの問題を抱えています、それは「ポインター」を表示しません…….
それで、カーソルを追加する必要なしにこの問題を解決する2つの方法があります:ポインタスタイル:
#
の代わりにjavascript:void(0)
を使用してください。
<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
ng-click
ディレクティブで$event.preventDefault()
を使用してください。
<a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
個人的には後者よりも前者の方が好きです。 javascript:void(0)
には他にも、 ここで説明した という利点があります。そのリンクには「目立たないJavaScript」という議論もありますが、これは非常に最近のことで、必ずしも角度のあるアプリケーションには直接当てはまりません。
あなたは次のようにすることができます
1.アンカー(href
)タグからa
属性を削除
2.クリック要素にcssでポインタカーソルを設定
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
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()
}
私が見ることができるこのオプションを試してみてくださいまだ上にリストされていません:
<a href="" ng-click="do()">Click</a>
Hrefのイベントを回避する最も安全な方法は、それを次のように定義することです。
<a href="javascript:void(0)" ....>
それでも関連がある場合:
<a ng-click="unselect($event)" />
...
scope.unselect = function( event ) {
event.preventDefault();
event.stopPropagation();
}
...
あなたはWebアプリを作っているので、なぜあなたはリンクを必要としますか?
アンカーをボタンに交換しましょう!
<button ng-click="do()"></button>
これは私がいつもすることです。魅力のように動作します!
<a href ng-click="do()">Click</a>
私は一緒に行きます:
<a ng-click="do()">Click</a>
このデフォルトを防ぐこと全体が私を混乱させているので、 私は JSFiddle を作成しました。いつどこで Angular がデフォルトを防いでいるかを示しています 。
JSFiddleはAngularのaディレクティブを使用しているので、まったく同じであるはずです。あなたはここでソースコードを見ることができます: タグソースコード
これが一部の人の説明に役立つことを願っています。
私はそのドキュメントをngHrefに投稿したいと思いましたが、評判が悪いのでできません。
インラインが必要な場合は、次のようにします。
<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>
たくさんの答えがやり過ぎるようです。私のために、これは働きます
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
(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>
もしhrefに行きたくないのなら...意味的にはアンカーやリンクではないので、マークアップを変更してアンカータグではなくボタンを使うべきです。逆に、チェックをしてからリダイレクトするボタンがある場合、それはボタンではなくリンク/アンカータグであるべきです... SEOの目的やテストのために[ここにテストスイートを挿入]。
変更を保存するか、またはダーティ状態を確認するように条件付きでのみリダイレクトするリンクの場合は、ng-click = "someFunction($ event)"を使用し、validationError preventDefaultまたはstopPropagationにsomeFunctionを使用する必要があります。
また あなたができるという理由だけであなたがそうすべきではないという理由で 。 javascript:void(0)は当時はうまく機能していました...しかし、悪意のあるハッカーやクラッカーのブラウザは、href内でjavascriptを使用するアプリやサイトにフラグを立てています。
2010年以降の2016年は、ボタンのように機能するリンクを使用する理由がどこにもないはずです。それでもIE8以下をサポートする必要がある場合は、事業所を再評価する必要があります。
テニスの答えから借りた。私はあなたがすべてのリンクを追加するためにカスタムディレクティブを作成する必要がないのが好きです。しかし、私は彼を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();
}
})
}
};
}
])
角度のあるブートストラップドロップダウンのためにアンカーを使用するとき、私はこれと同じ問題に遭遇しました。不要な副作用(preventDefault()を使用しているためドロップダウンが閉じない)を回避できることがわかった唯一の解決策は、次のとおりです。
<a href="javascript:;" ng-click="do()">Click</a>
目的を達成するために、$ locationのHtml5Mode内でURLリダイレクトを無効にすることができます。ページに使用されている特定のコントローラ内で定義できます。このようなもの:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
あなたがすべきことは、href
属性を完全に省略することです。
ソースコード を見ればa
elementディレクティブ(これはAngular coreの一部です)のために、29 - 31行目で述べています。
if (!element.attr(href)) {
event.preventDefault();
}
これはAngularがhrefなしでリンクの問題をすでに解決していることを意味します。あなたがまだ持っている唯一の問題はcss問題です。それでも、クリックスタイルのアンカーにポインタスタイルを適用することができます。
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
そのため、実際のリンクに微妙な異なるスタイルを付けて機能を実行するリンクをマークすることで、サイトをよりアクセスしやすくすることもできます。
ハッピーコーディング!