Acceda al evento para llamar a preventdefault desde la función personalizada que se origina en el atributo onclick de la etiqueta

119

Tengo enlaces como este:

<a href="#" onclick="myfunc({a:1, b:'hi'})" />click</a>
<a href="#" onclick="myfunc({a:3, b:'jo'})" />click</a>

Y me gustaría hacer un preventDefault()inside myfunc(), porque #se agregará un en la barra de direcciones al hacer clic en el enlace (sin hacer return false;o href='javascript:void(0);')

es posible? ¿Puedo llevar el evento adentro?myfunc()

Omu
fuente
6
¿Qué tiene de malo devolver falso?
Alex
5
también detiene la propagación
Omu
4
return falsesolo detiene la propagación dentro de jQuery.
cruzanmo

Respuestas:

157

Creo que puede pasar eventa la función en línea, que será el eventobjeto para el evento generado en los navegadores compatibles con W3C (es decir, las versiones anteriores de IE aún requerirán detección dentro de su función de controlador de eventos para ver window.event).

Un ejemplo rápido .

function sayHi(e) {
   e.preventDefault();
   alert("hi");
}
<a href="http://google.co.uk" onclick="sayHi(event);">Click to say Hi</a>

  1. Ejecútelo como está y observe que el enlace no redirecciona a Google después de la alerta.
  2. Luego, cambie el eventpaso al onclickcontrolador a algo más como e, haga clic en ejecutar, luego observe que la redirección tiene lugar después de la alerta (el panel de resultados se vuelve blanco, lo que demuestra una redirección).
Russ Cam
fuente
5
ok, veo que todo lo que tenía que hacer era poner mi parámetro en segundo lugarmyfunc(event, {a:123, b:"asdas"})
Omu
1
@Omu El argumento pasado, evento, puede estar en cualquier lugar, no tiene que ser el primero, siempre que esté en el lugar correcto de la lista de parámetros definida para la función. Por ejemplo, function myfunc(o, e) {...}entonces se puede llamar como myfunc({a:1, b:'hi'}, event).
cateyes
2
Creo que no es necesario pasar y capturar explícitamente el objeto de evento. Simplemente puede consultarlo en la función. ¿Alguien puede confirmar? Quiero decir, este código sin el evento también debería funcionar:function sayHi() { event.preventDefault(); alert("hi"); }
K Vij
111

La solución más simple simplemente es:

<a href="#" onclick="event.preventDefault(); myfunc({a:1, b:'hi'});" />click</a>

En realidad, es una buena manera de realizar la destrucción de caché para documentos con un respaldo para navegadores sin JS habilitado (sin prevención de caché si no hay JS)

<a onclick="
if(event.preventDefault) event.preventDefault(); else event.returnValue = false;
window.location = 'http://www.domain.com/docs/thingy.pdf?cachebuster=' + 
Math.round(new Date().getTime() / 1000);" 
href="http://www.domain.com/docs/thingy.pdf">

Si JavaScript está habilitado, abre el PDF con una cadena de consulta de eliminación de caché, si no, simplemente abre el PDF.

JuLo
fuente
Podría usar la tecnología del lado del servidor para reescribir ese enlace si lo único que busca es romper el caché.
mpen
Sería mejor, pero no tengo acceso al código del lado del servidor. Trabajando con lo que tengo.
JuLo
11

Prueba esto:

<script>
    $("a").click(function(event) {
        event.preventDefault(); 
    });
</script>
Suave Nti
fuente
esto requiere una etiqueta <script> para cada evento de clic, lo que hace que el código sea más complicado.
somid3
También requiere jQuery, que aunque esté presente no debería ser un requisito previo.
Cobertizo irregular
También no estoy de acuerdo aquí, un simple análisis de una función en línea es más efectivo y menos código.
Shannon Hochkins
1
@ somid3, mientras que jQuery no es necesario , si usted está preocupado por el rendimiento, se puede utilizar un único delegado controlador de eventos para que sólo está adjuntando un único procesador para todos los anclajes en la página de la siguiente manera: $("body").on("click","a",function(e) { e.preventDefault() });. En cualquier caso, ninguna de las soluciones tendrá un impacto significativo en el rendimiento.
KyleMit
7
<script type="text/javascript">
$('a').click(function(){
   return false;
});
<script>
Aram Mkrtchyan
fuente
2
Esto se aplica a cada ancla, y romperá todos los enlaces, también requiere que se inserte javascript en la página, así como jQuery.
Shannon Hochkins
Además, cuando se usa jQuery, return falseno se recomienda, ya que también evitará que se ejecuten todos los demás controladores de eventos en ese elemento y evitará que el evento se propague a elementos superiores.
Stijn de Witt
6

Agregue una clase única a los enlaces y un javascript que evite el defecto en los enlaces con esta clase:

<a href="#" class="prevent-default" 
   onclick="$('.comment .hidden').toggle();">Show comments</a>

<script>
  $(document).ready(function(){

    $("a.prevent-default").click(function(event) {
         event.preventDefault(); 
          });
  });
</script>
aaandre
fuente
Enfoque interesante para una solución global.
AFract
5

¿No puede simplemente eliminar el atributo href de la etiqueta a?

Leigh Ciechanowski
fuente
1
sí, esa también es una opción, aunque de forma predeterminada el enlace no tendrá subrayado, y si javascript está desactivado, no habrá href para ir
Omu
4

Creo que cuando usamos onClick queremos hacer algo diferente a lo predeterminado. Entonces, para todos sus enlaces con onClick:

$("a[onClick]").on("click", function(e) {
  return e.preventDefault();
});
Ronan
fuente
2

¡Sencillo!

onclick="blabla(); return false"
Jake
fuente
2

Puede acceder al evento desde un clic así:

<button onclick="yourFunc(event);">go</button>

y en su función de javascript, mi consejo es agregar esa declaración de primera línea como:

function yourFunc(e) {
    e = e ? e : event;
}

luego use en todas partes e como variable de evento

gdarcan
fuente
0

Sin ninguna biblioteca JS o jQuery. Para abrir una bonita ventana emergente si es posible. Falla de forma segura al enlace normal abierto.

<a href="https://acme.com/" onclick="onclick="openNewWindow(event, this.href);">...</a>

Y la función de ayudante:

function openNewWindow(event, location) {
  if (event.preventDefault && event.stopImmediatePropagation) { 
    event.preventDefault(); 
    event.stopImmediatePropagation(); 
  } else {
    event.returnValue = false; 
  }
  window.open(location, 'targetWindow', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=800,height=450');
}
Martin Večeřa
fuente