Como evitar erros em tags de âncora?

Digamos que eu tenha uma tag de âncora como

Click 

Como posso evitar que o navegador navegue para # no AngularJS ?

ATUALIZAÇÃO : Desde então, mudei de idéia nessa solução. Depois de mais desenvolvimento e tempo gasto trabalhando nisso, acredito que uma solução melhor para esse problema é fazer o seguinte:

 Click Here 

E então atualize seu css para ter uma regra extra:

 a[ng-click]{ cursor: pointer; } 

É muito mais simples e fornece a mesma funcionalidade e é muito mais eficiente. Espero que possa ser útil para qualquer pessoa que procure essa solução no futuro.


A seguir, minha solução anterior, que estou deixando aqui apenas para fins de legado:

Se você está tendo esse problema muito, uma diretiva simples que consertaria 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 ( ) para ver se o atributo href é uma string vazia ( "" ) ou um hash ( '#' ) ou se há uma atribuição ng-click . Se encontrar alguma destas condições, captura o evento e impede o comportamento padrão.

A única desvantagem é que ele executa essa diretiva para todas as tags de âncora. Portanto, se você tiver muitas tags de âncora na página e desejar apenas evitar o comportamento padrão de um pequeno número delas, essa diretiva não será muito eficiente. No entanto, eu quase sempre quero preventDefault , então eu uso toda essa diretiva nos meus aplicativos AngularJS.

De acordo com os documentos para o ngHref, você deve ser capaz de deixar o href ou href = “”.

 
link 1 (link, don't reload)
link 2 (link, don't reload)
anchor (link, don't reload)
anchor (no link)

Você pode passar o object $ event para seu método e chamar $event.preventDefault() , para que o processamento padrão não ocorra:

 Click // then in your controller.do($event) method $event.preventDefault() 

Eu prefiro usar diretivas para esse tipo de coisa. Aqui está um exemplo

 Click Me 

E o código da diretiva para eat-click :

 module.directive('eatClick', function() { return function(scope, element, attrs) { $(element).click(function(event) { event.preventDefault(); }); } }) 

Agora você pode adicionar o atributo eat-click a qualquer elemento e ele obterá preventDefault() ‘automagicamente.

Benefícios:

  1. Você não precisa passar o object de $event feio para sua function do() .
  2. Seu controlador é mais testável por unidade porque não precisa separar o object $event

Embora Renaud deu uma ótima solução

 Click 

Eu pessoalmente achei que você também precisa $ event.stopPropagation () em alguns casos para evitar alguns dos efeitos colaterais

  Click 

será minha solução

 ng-click="$event.preventDefault()" 

A solução mais fácil que encontrei é esta:

 Click 

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 este problema sem precisar adicionar um cursor: estilo de ponteiro:

  1. Use javascript:void(0) vez de # :

     Do Something 
  2. Use $event.preventDefault() na diretiva ng-click (para não sobrecarregar o seu controlador com referências relacionadas ao DOM):

     Do Something 

Pessoalmente, prefiro o primeiro ao segundo. javascript:void(0) tem outros benefícios que são discutidos aqui . Há também a discussão de “JavaScript discreto” nesse link, que é assustadoramente recente, e não se aplica necessariamente diretamente a um aplicativo angular.

Você pode fazer o seguinte

1. Remova o atributo href da tag anchor ( a )

Cursor do cursor 2.Set em css para ng click elementos

  [ng-click], [data-ng-click], [x-ng-click] { cursor: pointer; } 

HTML

aqui angularjs puro: próximo à function ng-click, você pode escrever a function preventDefault () separando ponto-e-vírgula

 Click me 

JS

 $scope.do = function() { alert("do here anything.."); } 

(ou)

você pode continuar assim, isso já é discutido aqui.

HTML

 Click me 

JS

 $scope.do = function(event) { event.preventDefault(); event.stopPropagation() } 

Tente esta opção que eu posso ver ainda não está listado acima:

 Click 

Desde que você está fazendo um aplicativo web porque você precisa de links?

Troque suas âncoras por botões!

  

se ainda relevante:

  ... scope.unselect = function( event ) { event.preventDefault(); event.stopPropagation(); } ... 

Eu iria com:

 Click 
  • porque, de acordo com os documentos, você deve ser capaz de sair do href e, em seguida, o Angular lidará com o padrão de prevenção para você!

Todo isso impedir coisa padrão tem sido confuso para mim, então eu criei um JSFiddle lá ilustrar quando e onde Angular está impedindo o padrão .

O JSFiddle está usando uma diretiva do Angular – então deve ser EXATAMENTE o mesmo. Você pode ver o código fonte aqui: um código fonte da tag

Espero que isso ajude a esclarecer alguns.

Eu teria gostado de postar o documento para o ngHref, mas não posso por causa da minha reputação.

Isso é o que eu sempre faço. Funciona como um encanto!

 Click 

A maneira mais segura de evitar events em um href seria defini-lo como

  

Ou se você precisar inline, então você pode fazer isso:

 Click to show 

Muitas respostas parecem ser exageradas. Para mim, isso funciona

  {{question.Verbiage}} 

Preciso da presença do valor do atributo href para degradação (quando js está desativado), então não posso usar o atributo vazio href (ou “#”), mas o código acima não funcionou para mim, porque eu 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:

 Sign up 

Emprestando da resposta do tenente. Eu gosto que você não precise criar uma diretiva personalizada para adicionar em todos os links. No entanto, eu não consegui o seu para trabalhar no IE8. Aqui está o que finalmente funcionou para mim (usando 1.0.6 angular).

Observe que ‘bind’ permite que você use jqLite fornecido pelo angular, então não há necessidade de envolver com 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(); } }) } }; } ]) 

Eu corri para este mesmo problema ao usar âncoras para uma lista suspensa de bootstrap angular. A única solução que encontrei que evitou efeitos colaterais indesejados (ou seja, a queda não fechando por causa de usar preventDefault ()) foi usar o seguinte:

  Click 

se você nunca quiser ir para href … você deve mudar sua marcação e usar um botão não uma tag de âncora porque semanticamente não é uma âncora ou um link. Inversamente, se você tiver um botão que faz algumas verificações e, em seguida, redireciona, deve ser uma tag de link / âncora e não um botão … para fins de SEO, bem como testes [insira o conjunto de testes aqui].

para links que você deseja redirect condicionalmente como solicitar salvar alterações ou reconhecer estado sujo … você deve usar ng-click = “someFunction ($ event)” e, em someFunction, em validationError preventDefault e ou stopPropagation.

também só porque você pode não significa que deveria . javascript: void (0) funcionou bem no passado … mas por causa dos navegadores nefandos de hackers / crackers sinalizam aplicativos / sites que usam javascript dentro de um href … não vejo razão para usar o ducktype acima ..

É 2016, desde 2010, não deve haver motivo para usar links que agem como botões … Se você ainda tem que suportar o IE8 e abaixo você precisa reavaliar o seu local de trabalho.

 /* 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 inteiramente o atributo href .

Se você olhar o código-fonte para a diretiva de a elemento (que faz parte do núcleo angular), ele indica na linha 29 – 31:

 if (!element.attr(href)) { event.preventDefault(); } 

O que significa Angular já está resolvendo a questão dos links sem um href. O único problema que você ainda tem é o problema do CSS. Você ainda pode aplicar o estilo de ponteiro a âncoras que tenham ng-cliques, por exemplo:

 a[ng-click] { /* Styles for anchors without href but WITH ng-click */ cursor: pointer; } 

Assim, você pode até tornar seu site mais acessível marcando links reais com um estilo sutil e diferente dos links que executam funções.

Codificação feliz!

Você pode desativar o redirecionamento de URL dentro do Html5Mode de $ location para atingir o objective. 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 }); }]); 

Uma alternativa pode ser:

 Click