Digamos que eu tenho uma tag de âncora como
<a href="#" ng-click="do()">Click</a>
Como impedir que o navegador navegue para # no AngularJS ?
href=''
para manter o comportamento do ponteiro do mouse.
Digamos que eu tenho uma tag de âncora como
<a href="#" ng-click="do()">Click</a>
Como impedir que o navegador navegue para # no AngularJS ?
href=''
para manter o comportamento do ponteiro do mouse.
Respostas:
ATUALIZAÇÃO : Desde então, mudei de idéia sobre esta solução. Após mais desenvolvimento e tempo gasto trabalhando nisso, acredito que uma solução melhor para esse problema é fazer o seguinte:
<a ng-click="myFunction()">Click Here</a>
E atualize seu css
para ter uma regra extra:
a[ng-click]{
cursor: pointer;
}
É muito mais simples e oferece exatamente a mesma funcionalidade e é muito mais eficiente. Espero que possa ser útil para quem procura essa solução no futuro.
A seguir, minha solução anterior, que deixo aqui apenas para fins de legado:
Se você está tendo esse problema muito, uma diretiva simples que corrija esse problema é a seguinte:
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();
});
}
}
};
});
Ele verifica todas as tags de âncora ( <a></a>
) para ver se seu href
atributo é uma string vazia ( ""
) ou um hash ( '#'
) ou se há uma ng-click
atribuição. Se encontrar alguma dessas condições, ele captura o evento e evita o comportamento padrão.
A única desvantagem é que ele executa essa diretiva para todas as tags âncora. Portanto, se você possui muitas tags âncora na página e deseja apenas impedir o comportamento padrão de um pequeno número delas, essa diretiva não é muito eficiente. No entanto, quase sempre quero preventDefault
, então uso essa diretiva em todos os meus aplicativos AngularJS.
href
atributo em branco tem comportamento variável em diferentes navegadores. Embora eu concorde que seja de longe a solução mais limpa e eficiente, ela tem alguns problemas entre navegadores. O uso da abordagem de diretiva permite que o navegador manipule a <a>
tag como faria normalmente, mas ainda obtendo ao OP a resposta que estava procurando.
De acordo com os documentos para ngHref, você deve deixar o href ou fazer 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 />
Você pode passar o objeto $ event para o seu método e invocá $event.preventDefault()
-lo, para que o processamento padrão não ocorra:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
$event.preventDefault()
... IE tax.
ng-click="do(); $event.preventDefault()
por exemplo ... embora não seja necessário porque a resposta de @ Chris abaixo é a correta. Isso pode ajudar as pessoas em situações nas quais eles aninharam ngClicks e desejam chamar $event.stopPropagation()
, no entanto.
Eu prefiro usar diretivas para esse tipo de coisa. Aqui está um exemplo
<a href="#" ng-click="do()" eat-click>Click Me</a>
E o código de diretiva para eat-click
:
module.directive('eatClick', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
event.preventDefault();
});
}
})
Agora você pode adicionar o eat-click
atributo a qualquer elemento e ele será preventDefault()
editado automaticamente.
Benefícios:
$event
objeto feio para sua do()
função.$event
objetoError: $ is not defined
. o que estou perdendo?
angular.element(element).bind('click', function(event){...});
. Funcionou. Re
Embora Renaud tenha dado uma ótima solução
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Pessoalmente, achei que você também precisa de $ event.stopPropagation () em alguns casos, para evitar alguns dos efeitos colaterais
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
será minha solução
ng-click="$event.preventDefault()"
A solução mais fácil que encontrei é esta:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Então, lendo essas respostas, o @Chris ainda tem a resposta mais "correta", suponho, mas tem um problema, não mostra o "ponteiro" ....
Então, aqui estão duas maneiras de resolver esse problema sem precisar adicionar um cursor: estilo do ponteiro:
Use em javascript:void(0)
vez de #
:
<a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
Use $event.preventDefault()
na ng-click
diretiva (para não desperdiçar seu controlador com referências relacionadas ao DOM):
<a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
Pessoalmente, prefiro o primeiro do que o último. javascript:void(0)
tem outros benefícios discutidos aqui . Há também discussões sobre "JavaScript discreto" nesse link assustadoramente recente e que não se aplica necessariamente diretamente a um aplicativo angular.
javascript:;
Você pode fazer o seguinte
1.Remova o href
atributo da a
marca anchor ( )
2. Defina o cursor do ponteiro em css para ng clique em elementos
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
HTML
aqui angularjs puros: perto da função ng-click, você pode escrever a função preventDefault () separando ponto e vírgula
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">Click me</a>
JS
$scope.do = function() {
alert("do here anything..");
}
(ou)
você pode continuar dessa maneira, isso já é discutido aqui.
HTML
<a href="#" ng-click="do()">Click me</a>
JS
$scope.do = function(event) {
event.preventDefault();
event.stopPropagation()
}
Como você está criando um aplicativo Web, por que precisa de links?
Troque suas âncoras para botões!
<button ng-click="do()"></button>
A maneira mais segura de evitar eventos em um href seria defini-lo como
<a href="javascript:void(0)" ....>
Eu iria com:
<a ng-click="do()">Click</a>
Toda essa coisa de impedir o padrão foi confusa para mim, então eu criei um JSFiddle lá para ilustrar quando e onde o Angular está impedindo o padrão .
O JSFiddle está usando uma diretiva angular - portanto deve ser EXATAMENTE o mesmo. Você pode ver o código fonte aqui: um código fonte de tag
Espero que isso ajude a esclarecer alguns.
Eu gostaria de postar o documento no ngHref, mas não posso por causa da minha reputação.
É isso que eu sempre faço. Funciona como um encanto!
<a href ng-click="do()">Click</a>
Muitas respostas parecem ser um exagero. Para mim, isso funciona
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
Eu preciso da presença do valor do atributo href para degradação (quando js está desativado), portanto não posso usar o atributo href vazio (ou "#"), mas o código acima não funcionou para mim, porque preciso de um evento ( e) variável. Eu criei minha própria diretiva:
angular.module('MyApp').directive('clickPrevent', function() {
return function(scope, element, attrs) {
return element.on('click', function(e) {
return e.preventDefault();
});
};
});
Em HTML:
<a data-click-prevent="true" href="/users/sign_up" ng-click="openSignUpModal()">Sign up</a>
Tomando emprestado a resposta de tennisgent. Eu gosto que você não precisa criar uma diretiva personalizada para adicionar todos os links. No entanto, eu não consegui fazê-lo trabalhar no IE8. Aqui está o que finalmente funcionou para mim (usando o angular 1.0.6).
Observe que 'bind' permite que você use o jqLite fornecido pelo angular, portanto não há necessidade de envolver o jQuery completo. Também é necessário o método 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
, quero a propagação, mas não o comportamento padrão. Este trecho NÃO é recomendado.
Corri para esse mesmo problema ao usar âncoras para uma lista de inicialização angular suspensa. A única solução que descobri que evitou efeitos colaterais indesejados (ou seja, a lista suspensa que não fechava por causa do preventDefault ()) era usar o seguinte:
<a href="javascript:;" ng-click="do()">Click</a>
se você nunca quiser acessar o href ... altere sua marcação e use um botão que não seja uma marca de âncora, porque semanticamente não é uma âncora ou um link. Inversamente, se você tem um botão que faz algumas verificações e depois o redireciona, deve ser uma tag de link / âncora e não um botão ... para fins de SEO e testes [insira o conjunto de testes aqui].
para links que você deseja redirecionar apenas condicionalmente, como solicitar salvar alterações ou reconhecer estado sujo ... você deve usar ng-click = "someFunction ($ event)" e em someFunction em seu validationError preventDefault e ou stopPropagation.
também só porque você pode, não significa que deveria . javascript: void (0) funcionou bem antigamente ... mas por causa dos nefastos navegadores de hackers / crackers sinalizam aplicativos / sites que usam javascript dentro de um href ... não há motivo para digitar acima ..
é 2016 desde 2010, não deve haver razão para usar links que funcionam como botões ... se você ainda precisa dar suporte ao IE8 e abaixo, precisa reavaliar seu local de negócios.
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
O que você deve fazer é omitir o href
atributo completamente.
Se você olhar para o código-fonte da a
diretiva de elemento (que faz parte do núcleo Angular), ela declara nas linhas 29 a 31:
if (!element.attr(href)) {
event.preventDefault();
}
O que significa que o Angular já está resolvendo o problema de links sem um href. O único problema que você ainda tem é o problema de css. Você ainda pode aplicar o estilo do ponteiro às âncoras com cliques em ng, por exemplo:
a[ng-click] {
/* Styles for anchors without href but WITH ng-click */
cursor: pointer;
}
Assim, você pode tornar seu site mais acessível, marcando links reais com um estilo sutil e diferente dos links que executam funções.
Feliz codificação!
Você pode desativar o redirecionamento de URL no Html5Mode de $ location para atingir o objetivo. Você pode defini-lo dentro do controlador específico usado para a página. Algo assim:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
Se você estiver usando o Angular 8 ou mais, poderá criar uma diretiva:
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();
}
}
Na sua âncora no componente, você pode conectá-lo da seguinte maneira:
<a ngbDropdownToggle preventDefault class="nav-link dropdown-toggle" href="#" aria-expanded="false" aria-haspopup="true" id="nav-dropdown-2">Pages</a>
O módulo de aplicativo deve ter sua declaração:
import { PreventDefaultDirective } from './shared/directives/preventdefault.directive';
@NgModule({
declarations: [
AppComponent,
PreventDefaultDirective
Uma alternativa pode ser:
<span ng-click="do()">Click</span>
span
para clicar. Basta ir para a resposta do @ tennisgent - âncoras sem href
definição.
href
.