¿Cómo prevenirDefault en las tags de anclaje?

Digamos que tengo una etiqueta de anclaje como

Click 

¿Cómo puedo evitar que el navegador navegue a # en AngularJS ?

ACTUALIZACIÓN : Desde entonces he cambiado de opinión sobre esta solución. Después de más desarrollo y tiempo dedicado a trabajar en esto, creo que una mejor solución a este problema es hacer lo siguiente:

 Click Here 

Y luego actualiza tu css para tener una regla adicional:

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

Es mucho más simple y proporciona exactamente la misma funcionalidad y es mucho más eficiente. Espero que pueda ser útil para cualquier otra persona que busque esta solución en el futuro.


La siguiente es mi solución anterior, que dejo aquí solo con fines heredados:

Si tiene este problema mucho, una directiva simple que solucionaría este problema es la siguiente:

 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(); }); } } }; }); 

Comprueba todas las tags de anclaje ( ) para ver si su atributo href es una cadena vacía ( "" ) o un hash ( '#' ) o hay una asignación ng-click . Si encuentra alguna de estas condiciones, detecta el evento y evita el comportamiento predeterminado.

El único inconveniente es que ejecuta esta directiva para todas las tags de anclaje. Por lo tanto, si tiene muchas tags de anclaje en la página y solo desea evitar el comportamiento predeterminado para una pequeña cantidad de ellas, entonces esta directiva no es muy eficiente. Sin embargo, casi siempre quiero evitar preventDefault , así que uso esta directiva en todas mis aplicaciones AngularJS.

De acuerdo con los documentos de ngHref , debería poder dejar el href o hacer href = “”.

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

Puede pasar el objeto $ event a su método y llamar a $event.preventDefault() en él, de modo que no se produzca el procesamiento predeterminado:

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

Prefiero usar directivas para este tipo de cosas. Aquí hay un ejemplo

 Click Me 

Y el código de la directiva para eat-click :

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

Ahora puede agregar el atributo eat-click a cualquier elemento y obtendrá preventDefault() ‘ed automágicamente.

Beneficios:

  1. No tiene que pasar el objeto feo $event a su función do() .
  2. Su controlador es más verificable por unidad porque no necesita anular el objeto $event

Aunque Renaud dio una gran solución

 Click 

Personalmente encontré que también necesita $ event.stopPropagation () en algunos casos para evitar algunos de los efectos secundarios

  Click 

será mi solución

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

La solución más fácil que he encontrado es esta:

 Click 

Entonces, al leer estas respuestas, @Chris todavía tiene la respuesta más “correcta”, supongo, pero tiene un problema, no muestra el “puntero” …

Así que aquí hay dos formas de resolver este problema sin necesidad de agregar un cursor: estilo de puntero:

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

     Do Something 
  2. Use $event.preventDefault() en la directiva ng-click (para que no descargue su controlador con referencias relacionadas con DOM):

     Do Something 

Personalmente prefiero lo primero a lo último. javascript:void(0) tiene otros beneficios que se tratan aquí . También se habla de “JavaScript discreto” en ese enlace que es terriblemente reciente, y no necesariamente se aplica directamente a una aplicación angular.

Puedes hacer lo siguiente

1. Eliminar el atributo href de la etiqueta de anclaje ( a )

2. Ponga el cursor del puntero en CSS para hacer clic en los elementos

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

HTML

aquí angularjs puro: cerca de la función ng-click puede escribir la función preventDefault () separando punto y coma

 Click me 

JS

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

(o)

puede proceder de esta manera, esto ya se discutió aquí.

HTML

 Click me 

JS

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

Pruebe esta opción que puedo ver aún no mencionada arriba:

 Click 

Como estás haciendo una aplicación web, ¿por qué necesitas enlaces?

¡Cambia tus anclajes a botones!

  

si aún es relevante:

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

Yo iría con:

 Click 
  • ¡porque de acuerdo con los documentos, debería poder abandonar el href y luego Angular manejará la prevención predeterminada para usted!

Todo esto previene lo predeterminado ha sido confuso para mí, así que he creado un JSFiddle allí ilustra cuándo y dónde Angular está impidiendo el valor predeterminado .

JSFiddle usa una directiva de Angular, por lo que debe ser EXACTAMENTE la misma. Aquí puede ver el código fuente: un código fuente de etiqueta

Espero que esto ayude a la aclaración de algunos.

Me hubiera gustado publicar el documento en ngHref pero no puedo debido a mi reputación.

Esto es lo que siempre hago. ¡Funciona de maravilla!

 Click 

La forma más segura de evitar eventos en un href sería definirlo como

  

O si necesita en línea, puede hacer esto:

 Click to show 

Muchas respuestas parecen ser excesivas. PARA MÍ, esto funciona

  {{question.Verbiage}} 

Necesito una presencia del valor del atributo href para la degradación (cuando js está desactivado), así que no puedo usar el atributo href vacío (o “#”), pero el código anterior no me funcionó, porque necesito un evento ( e) variable. Creé mi propia directiva:

 angular.module('MyApp').directive('clickPrevent', function() { return function(scope, element, attrs) { return element.on('click', function(e) { return e.preventDefault(); }); }; }); 

En HTML:

 Sign up 

Tomando prestado de la respuesta de Tennisgent. Me gusta que no tenga que crear una directiva personalizada para agregar todos los enlaces. Sin embargo, no pude hacer que su trabajo en IE8. Esto es lo que finalmente funcionó para mí (usando angular 1.0.6).

Tenga en cuenta que ‘bind’ le permite usar jqLite proporcionado por angular, por lo que no es necesario ajustarlo con jQuery completo. También se requiere el 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(); } }) } }; } ]) 

Me encontré con este mismo problema cuando uso anclajes para un menú desplegable angular de arranque. La única solución que encontré que evitaba los efectos secundarios no deseados (es decir, el menú desplegable no se cerraba debido al uso de preventDefault ()) era usar lo siguiente:

  Click 

si no quiere ir nunca a href … debe cambiar su marcado y usar un botón y no una etiqueta de anclaje porque semánticamente no es un anclaje o un enlace. A la inversa, si tiene un botón que realiza algunas comprobaciones y luego lo redirecciona debe ser una etiqueta de enlace / anclaje y no un botón … para fines de SEO, así como para probar [inserte el banco de pruebas aquí].

para los enlaces que solo desea redirigir condicionalmente, como solicitar cambios guardados, o confirmar el estado sucio … debe usar ng-click = “someFunction ($ event)” y en alguna función en suvaltiontionError preventDefault y / o stopPropagation.

también solo porque puedes no significa que deberías . javascript: void (0) funcionaba bien en el día … pero debido a los necios piratas informáticos / crackers, los navegadores marcan aplicaciones / sitios que usan javascript dentro de un href … no ven razón para usar el tipo anterior.

es 2016 desde 2010 no debería ser razón alguna para usar enlaces que actúen como botones … si todavía tiene que admitir IE8 y abajo, necesita volver a evaluar su lugar de trabajo.

 /* NG CLICK PREVENT DEFAULT */ app.directive('ngClick', function () { return { link: function (scope, element, attributes) { element.click(function (event) { event.preventDefault(); event.stopPropagation(); }); } }; }); 

Lo que debes hacer es omitir por completo el atributo href .

Si nos fijamos en el código fuente de la directiva a element (que es una parte del núcleo angular), indica en la línea 29 – 31:

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

Lo que significa que Angular ya está resolviendo el problema de los enlaces sin un href. El único problema que todavía tienes es el problema de CSS. Todavía puede aplicar el estilo del puntero a los anclajes que tienen ng-clicks, por ejemplo:

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

Por lo tanto, incluso podría hacer que su sitio sea más accesible marcando los enlaces reales con un estilo sutil y diferente, luego los enlaces que realizan funciones.

Feliz encoding!

Puede deshabilitar la redirección de URL dentro de $ location Html5Mode para lograr el objective. Puede definirlo dentro del controlador específico utilizado para la página. Algo como esto:

 app.config(['$locationProvider', function ($locationProvider) { $locationProvider.html5Mode({ enabled: true, rewriteLinks: false, requireBase: false }); }]); 

Una alternativa podría ser:

 Click