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 csspara 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 hrefatributo é uma string vazia ( "") ou um hash ( '#') ou se há uma ng-clickatribuiçã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.
hrefatributo 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-clickatributo a qualquer elemento e ele será preventDefault()editado automaticamente.
Benefícios:
$eventobjeto feio para sua do()função.$eventobjetoError: $ 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-clickdiretiva (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 hrefatributo da amarca 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 hrefatributo completamente.
Se você olhar para o código-fonte da adiretiva 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>
spanpara clicar. Basta ir para a resposta do @ tennisgent - âncoras sem hrefdefinição.
href.