Función de JavaScript en href vs. onclick

475

Quiero ejecutar una función de JavaScript simple con un clic sin ninguna redirección.

¿Hay alguna diferencia o beneficio entre poner la llamada de JavaScript en el hrefatributo (como este:

<a href="javascript:my_function();window.print();">....</a>

) vs. ponerlo en el onclickatributo (vincularlo al onclickevento)?

SkunkSpinner
fuente
55
Esta pregunta se ha discutido antes: stackoverflow.com/questions/245868/…
SolutionYogi

Respuestas:

276

Poner el onclick dentro del href ofendería a aquellos que creen firmemente en la separación del contenido del comportamiento / acción. El argumento es que su contenido html debe permanecer enfocado únicamente en el contenido, no en la presentación o el comportamiento.

La ruta típica en estos días es usar una biblioteca javascript (por ejemplo, jquery) y crear un controlador de eventos usando esa biblioteca. Se vería algo así como:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );
Desfile
fuente
1
O mootools, prototipos, dojo ... o simplemente en javascript, pero eso sería mucho más código pero vale la pena el ejercicio.
Ryan Florence
15
Si no tiene que hacer nada con el objeto de evento, JavaScript simple es bastante simple. Obtenga el nodo DOM con obj = document.getElementById (), luego configure obj.onclick = foo
Matt Bridges el
1
¿Qué pasa con la separación de contenido cuando el <a href> se genera sobre la marcha, digamos, en una ventana emergente, y aún necesita un comportamiento de clic especial?
Serge
66
¿Pero no era la pregunta sobre la diferencia entre poner la llamada JS en hreflínea versus en línea onclick? Asumiendo que ibas a ponerlo en línea por alguna razón, ¿cuál deberías usar? (En la práctica, haría lo que me sugirió, pero parece que se ha saltado la diferencia entre los dos atributos)
Nnnnnn
1
La única vez que recomendaría poner la llamada de función en línea frente a tener un evento onclick para el enlace es si está creando dinámicamente enlaces dentro de la página que llamarán a la misma función pero pueden no tener identificadores únicos. Tengo un formulario web donde el usuario puede agregar y eliminar elementos y pongo el clic en la parte inferior de los enlaces dentro de los divs creados dinámicamente para que pueda comenzar más rápido a procesar el script en lugar de usar algo menos específico como una identificación relativa o nombre de la clase.
MistyDawn
977

malo:

<a id="myLink" href="javascript:MyFunction();">link text</a>

bueno:

<a id="myLink" href="#" onclick="MyFunction();">link text</a>

mejor:

<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>

aún mejor 1:

<a id="myLink" title="Click to do something"
 href="#" onclick="MyFunction();return false;">link text</a>

aún mejor 2:

<a id="myLink" title="Click to do something"
 href="PleaseEnableJavascript.html" onclick="MyFunction();return false;">link text</a>

¿Por qué mejor? porque return falseevitará que el navegador siga el enlace

mejor:

Use jQuery u otro marco similar para adjuntar el controlador onclick por ID de elemento.

$('#myLink').click(function(){ MyFunction(); return false; });
demp
fuente
21
Habría otra solución que sería la mejor cuando hrefno se establece #sino en un enlace real para los navegadores noJS.
helly0d
66
¿Qué pasa si te digo que solo el primero (malo) funciona de la misma manera (correcta) en todos los navegadores con el clic central?
Vloxxity
14
¿Qué tiene de malo <a id="myLink" href="javascript:MyFunction();">?
Vaddadi Kartick
66
Solo mis humildes 5 centavos: la "mejor" opción sería usar botones para clics (¿eventos de clic?) Y dejar anclas con sus href a cuál era su intención de diseño original en primer lugar: ser anclas para enlaces a otras páginas.
nidalpres
44
El enlace al hacer clic con JavaScript tiene una desventaja: más tarde, cuando depure a alguien más su forma, es realmente difícil encontrar dónde y qué tipo de JavaScript se vincula a ese elemento.
Maarten Kieft
69

En términos de javascript , una diferencia es que la thispalabra clave en el onclickcontrolador se referirá al elemento DOM cuyo onclickatributo es (en este caso, el <a>elemento), mientras que thisen el hrefatributo se referirá awindow objeto.

En términos de presentación , si un hrefatributo está ausente de un enlace (es decir <a onclick="[...]">), por defecto, los navegadores mostrarán el textcursor (y no el pointercursor deseado a menudo ) ya que está tratando el<a> como un ancla, y no como un enlace.

En términos de comportamiento , al especificar una acción mediante la navegación a través de href, el navegador normalmente admitirá abrirla hrefen una ventana separada utilizando un acceso directo o un menú contextual. Esto no es posible cuando se especifica una acción solo a través de onclick.


Sin embargo, si está preguntando cuál es la mejor manera de obtener una acción dinámica con el clic de un objeto DOM, entonces adjuntar un evento usando javascript separado del contenido del documento es la mejor manera de hacerlo. Podrías hacer esto de varias maneras. Una forma común es usar una biblioteca javascript como jQuery para vincular un evento:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<a id="link" href="http://example.com/action">link text</a>
<script type="text/javascript">
    $('a#link').click(function(){ /* ... action ... */ })
</script>
Adán
fuente
99
Gracias por confirmar mi sospecha de que "esto" es diferente en "href" frente a "onclick".
joonas.fi
17

yo suelo

Click <a nohref style="cursor:pointer;color:blue;text-decoration:underline"
onClick="alert('Hello World')">HERE</a>

Un largo camino pero hace el trabajo. usa un estilo A para simplificar y luego se convierte en:

<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style> 
<a nohref onClick="alert('Hello World')">HERE</a>
Clif Collins
fuente
10
+1 Realmente genial! :-) Nunca había escuchado sobre nohrefatributos antes. Esta es la forma más lógica / elegante de manejar tales acciones de JavaScript. Esto es compatible con FF12 e IE8. Por lo tanto, reemplazaré todo mi href="JavaScript:void(0);"por nohref. Muchas gracias. Salud.
olibre
77
no es compatible con los principales navegadores, ¿por qué deberíamos usar esto? w3schools.com/tags/att_area_nohref.asp
hetaoblog
11
nohrefes parte de la areaetiqueta, no a! Su ejemplo es el mismo que<a onClick="alert('Hello World')">HERE</a>
nZeus
66
Simplemente otro "no hagas esta advertencia". Este es un consejo completamente no estándar y malo. nohrefno existe en una aetiqueta.
Colin 't Hart
11

Además de todo lo aquí, el href se muestra en la barra de estado del navegador, y no haga clic en. Creo que no es fácil de usar mostrar código JavaScript allí.

Kamarey
fuente
10

La mejor manera de hacerlo es con:

<a href="#" onclick="someFunction(e)"></a>

El problema es que esto agregará un hash (#) al final de la URL de la página en el navegador, lo que requiere que el usuario haga clic en el botón Atrás dos veces para ir a la página anterior a la suya. Teniendo esto en cuenta, debe agregar algo de código para detener la propagación de eventos. La mayoría de los kits de herramientas de JavaScript ya tendrán una función para esto. Por ejemplo, el kit de herramientas dojo usa

dojo.stopEvent(event);

para hacerlo

linusthe3rd
fuente
99
Me gustaría advertir que si utiliza href="#"el navegador buscará una etiqueta de anclaje con nombre y, dado que no la encuentra, hará que la ventana se desplace hacia la parte superior de la página, algo que podría no ser notable si ya estás en la cima. Para evitar este comportamiento, utilice: en su href="javascript:;"lugar.
alonso.torres
1
@ alonso.torres Buen punto, pero es por eso que mencioné el uso de dojo.stopEvent (): detendrá la propagación de eventos / burbujeo y el comportamiento predeterminado de hacer clic en el ancla.
linusthe3rd
77
En lugar de stopEvent, ¿por qué no simplemente devolver false (onclick = "someFunction (e); return false;")
stracktracer
10

La respuesta principal es una muy mala práctica, nunca se debe vincular a un hash vacío, ya que puede crear problemas en el futuro.

Sin embargo, lo mejor es vincular un controlador de eventos al elemento como lo han declarado muchas otras personas, <a href="javascript:doStuff();">do stuff</a> funciona perfectamente en todos los navegadores modernos, y lo uso ampliamente cuando renderizo plantillas para evitar tener que volver a vincular para cada instancia. En algunos casos, este enfoque ofrece un mejor rendimiento. YMMV

Otro tid-bit interesante ...

onclick& hreftener comportamientos diferentes al llamar a JavaScript directamente.

onclickpasará el thiscontexto correctamente, mientras hrefque no lo hará, o en otras palabras <a href="javascript:doStuff(this)">no context</a>, no funcionará, mientras que<a onclick="javascript:doStuff(this)">no context</a> hará.

Sí, omití el href. Si bien eso no sigue las especificaciones, funcionará en todos los navegadores, aunque, idealmente, debería incluir una href="javascript:void(0);"buena medida

Eduardo
fuente
8

Teniendo javascript: un atributo que no sea específicamente para secuencias de comandos es un método obsoleto de HTML. Si bien técnicamente funciona, todavía está asignando propiedades de JavaScript a un atributo que no es un script, lo cual no es una buena práctica. Incluso puede fallar en los navegadores antiguos, o incluso en algunos modernos (una publicación en el foro de Google parece indicar que a Opera no le gustan las URL 'javascript:').

Una mejor práctica sería la segunda forma, poner su javascript en el onclickatributo, que se ignora si no hay funcionalidad de scripting disponible. Coloque una URL válida en el campo href (comúnmente '#') para los que no tienen javascript.

zombat
fuente
1
No veo cómo hay alguna diferencia entre un 'javascript:' href y un '#' href con un atributo onclick. Ambos son igualmente inútiles para los navegadores sin JS habilitado.
harto el
2
harto, eso no es realmente correcto. '#' es un indicador para un enlace con nombre, no es un identificador de JavaScript. Es una URL válida y no requiere que se reconozca Javascript.
zombat el
8

funcionó para mí usando esta línea de código:

<a id="LinkTest" title="Any Title"  href="#" onclick="Function(); return false; ">text</a>
Omar Yassin Carcelen
fuente
7

Esto funciona

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>
TitusMix
fuente
3
¡Bienvenido a Stack Overflow! Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código. ¡Intente también no saturar su código con comentarios explicativos, ya que esto reduce la legibilidad tanto del código como de las explicaciones!
Goodbye StackExchange
2
Este código no funciona return: falso no es válido Debe ser devuelto falso.
hbulens
5

Personalmente, encuentro molesto poner llamadas de JavaScript en la etiqueta HREF. Por lo general, realmente no presto atención a si algo es o no un enlace de JavaScript o no, y muchas veces quiero abrir cosas en una nueva ventana. Cuando trato de hacer esto con uno de estos tipos de enlaces, aparece una página en blanco sin nada y JavaScript en mi barra de ubicación. Sin embargo, esto se evita un poco al usar un onlick.

Peter
fuente
3

Una cosa más que noté al usar "href" con javascript:

El script en el atributo "href" no se ejecutará si la diferencia de tiempo entre 2 clics fue bastante corta.

Por ejemplo, intente ejecutar el siguiente ejemplo y haga doble clic (¡rápido!) En cada enlace. El primer enlace se ejecutará solo una vez. El segundo enlace se ejecutará dos veces.

<script>
function myFunc() {
    var s = 0;
    for (var i=0; i<100000; i++) {
        s+=i;
    }
    console.log(s);
}
</script>
<a href="javascript:myFunc()">href</a>
<a href="#" onclick="javascript:myFunc()">onclick</a>

Reproducido en Chrome (doble clic) e IE11 (con triple clic). En Chrome, si hace clic lo suficientemente rápido, puede hacer 10 clics y tener solo 1 función de ejecución.

Firefox funciona bien.

kolobok
fuente
3

Primero, tener la URL hrefes mejor porque permite a los usuarios copiar enlaces, abrirlos en otra pestaña, etc.

En algunos casos (por ejemplo, sitios con cambios frecuentes de HTML) no es práctico vincular enlaces cada vez que hay una actualización.

Método de enlace típico

Enlace normal:

<a href="https://www.google.com/">Google<a/>

Y algo así para JS:

$("a").click(function (e) {
    e.preventDefault();
    var href = $(this).attr("href");
    window.open(href);
    return false;
});

Los beneficios de este método son la separación limpia de marcado y comportamiento y no tiene que repetir las llamadas a funciones en cada enlace.

Método sin enlace

Sin embargo, si no desea vincular cada vez, puede usar onclick y pasar el elemento y el evento, por ejemplo:

<a href="https://www.google.com/" onclick="return Handler(this, event);">Google</a>

Y esto para JS:

function Handler(self, e) {
    e.preventDefault();
    var href = $(self).attr("href");
    window.open(href);
    return false;
}

El beneficio de este método es que puede cargar nuevos enlaces (por ejemplo, a través de AJAX) siempre que lo desee sin tener que preocuparse por el enlace cada vez.

jchavannes
fuente
1
 <hr>
            <h3 class="form-signin-heading"><i class="icon-edit"></i> Register</h3>
            <button data-placement="top" id="signin_student" onclick="window.location='signup_student.php'" id="btn_student" name="login" class="btn btn-info" type="submit">Student</button>
            <div class="pull-right">
                <button data-placement="top" id="signin_teacher" onclick="window.location='guru/signup_teacher.php'" name="login" class="btn btn-info" type="submit">Teacher</button>
            </div>
        </div>
            <script type="text/javascript">
                $(document).ready(function(){
                $('#signin_student').tooltip('show'); $('#signin_student').tooltip('hide');
                });
            </script>   
            <script type="text/javascript">
                $(document).ready(function(){
                $('#signin_teacher').tooltip('show'); $('#signin_teacher').tooltip('hide');
                });
            </script>   
Andrés
fuente
0

Experimenté que el javascript: hrefs no funcionaba cuando la página estaba incrustada en la función de página web de Outlook donde una carpeta de correo está configurada para mostrar una url

cristiano
fuente