Função JavaScript em href vs. onclick

474

Eu quero executar uma função JavaScript simples em um clique sem redirecionar.

Existe alguma diferença ou benefício entre colocar a chamada JavaScript no hrefatributo (assim:

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

) vs. colocá-lo no onclickatributo (vinculando-o ao onclickevento)?

SkunkSpinner
fonte
5
Esta questão tem sido discutida antes: stackoverflow.com/questions/245868/...
SolutionYogi

Respostas:

276

Colocar o onclick dentro do href ofenderia aqueles que acreditam fortemente na separação do conteúdo do comportamento / ação. O argumento é que seu conteúdo html deve permanecer focado apenas no conteúdo, não na apresentação ou no comportamento.

O caminho típico atualmente é usar uma biblioteca javascript (por exemplo, jquery) e criar um manipulador de eventos usando essa biblioteca. Seria algo como:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );
Parand
fonte
1
Ou mootools, prototype, dojo ... ou simples em javascript, mas isso seria muito mais código, mas valeria o exercício.
22919 Ryan Florence
15
Se você não precisa fazer nada com o objeto de evento, o javascript simples é bastante simples. -Se o nó DOM com obj = document.getElementById (), em seguida, definir obj.onclick = foo
Matt Pontes
1
e a separação do conteúdo quando o <a href> é gerado em tempo real, digamos, em uma janela pop-up e você ainda precisa de um comportamento especial de clique?
Serge
6
Mas a pergunta não estava perguntando sobre a diferença entre colocar a chamada JS inline hrefversus inline in onclick? Supondo que você o colocaria em linha por algum motivo, qual você deveria usar? (Na prática, eu faria o que você sugeriu, mas você parece ter pulado a diferença entre os dois atributos.)
nnnnnn
1
A única vez que eu defenderia colocar a chamada de função em linha versus ter um evento onclick para o link é se você estiver criando dinamicamente links dentro da página que todos chamarão a mesma função, mas podem não ter IDs exclusivos. Eu tenho um formulário da web em que o usuário pode adicionar e remover itens e coloco o onclick no href dos links nos divs criados dinamicamente para que eu possa começar mais rapidamente o processamento do script em vez de usar algo menos específico, como um ID relativo ou nome da classe.
MisturaDawn
976

ruim:

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

Boa:

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

Melhor:

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

ainda melhor 1:

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

ainda melhor 2:

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

Por que melhor? porque return falseimpedirá que o navegador siga o link

melhor:

Use jQuery ou outra estrutura semelhante para anexar o manipulador onclick pelo ID do elemento.

$('#myLink').click(function(){ MyFunction(); return false; });
demp
fonte
21
Haveria outra solução que seria a melhor onde hrefnão está configurada, #mas como um link real para os navegadores noJS.
helly0d
6
E se eu lhe disser que apenas o primeiro (ruim) funciona da mesma maneira (à direita) em todos os navegadores com o clique no meio.
Vloxxity
14
O que há de ruim no <a id="myLink" href="javascript:MyFunction();">?
Vaddadi Kartick
6
Apenas meus humildes 5 centavos: a melhor opção seria usar botões para cliques (eventos ao clicar?) E deixar âncoras com seus hrefs para o que era sua intenção original de design em primeiro lugar: ser âncoras para links para outras páginas.
Nidalpres
4
A ligação ao clicar com javascript tem uma desvantagem: mais tarde, quando você está depurando outra pessoa do formulário, é realmente difícil encontrar onde e que tipo de javascript está vinculando esse elemento.
Maarten Kieft
69

Em termos de javascript , uma diferença é que a thispalavra - chave no onclickmanipulador se refere ao elemento DOM cujo onclickatributo é (nesse caso, o <a>elemento), enquanto que thisno hrefatributo se refere ao windowobjeto.

Em termos de apresentação , se um hrefatributo estiver ausente em um link (ou seja <a onclick="[...]">), então, por padrão, os navegadores exibirão o textcursor (e não o pointercursor frequentemente desejado ), pois estão tratando o item <a>como uma âncora e não como um link.

Em termos de comportamento , ao especificar uma ação pela navegação via href, o navegador normalmente suporta a abertura hrefem uma janela separada usando um atalho ou menu de contexto. Isso não é possível ao especificar uma ação apenas via onclick.


No entanto, se você está perguntando qual é a melhor maneira de obter ação dinâmica com o clique de um objeto DOM, anexar um evento usando javascript separado do conteúdo do documento é o melhor caminho a percorrer. Você poderia fazer isso de várias maneiras. Uma maneira comum é usar uma biblioteca javascript como jQuery para vincular um 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ão
fonte
9
Obrigado por confirmar minha suspeita de que "isto" seja diferente em "href" vs "onclick".
joonas.fi
17

eu uso

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

Um longo caminho, mas ele faz o trabalho. use um estilo A para simplificar, então ele se torna:

<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style> 
<a nohref onClick="alert('Hello World')">HERE</a>
Clif Collins
fonte
10
+1 Realmente ótimo! :-) Eu nunca tinha ouvido falar sobre nohrefatributo antes. Essa é a maneira mais lógica / elegante de lidar com essas ações javascript. Isso é compatível com FF12 e IE8. Portanto, substituirei todo o meu href="JavaScript:void(0);"por nohref. Muito obrigado. Felicidades.
olibre
7
não é suportado pelos principais navegadores, por que devemos usar isso? w3schools.com/tags/att_area_nohref.asp
hetaoblog
11
nohreffaz parte da areatag, não a! Seu exemplo é o mesmo que<a onClick="alert('Hello World')">HERE</a>
nZeus 27/05
6
Apenas outro "não faça este aviso". Este é um conselho completamente fora do padrão e ruim. nohrefnão existe em uma atag.
Colin 't Hart
11

Além de tudo aqui, o href é mostrado na barra de status do navegador e não clica em não. Eu acho que não é fácil mostrar o código javascript lá.

Kamarey
fonte
10

a melhor maneira de fazer isso é com:

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

O problema é que isso adicionará um hash (#) ao final do URL da página no navegador, exigindo que o usuário clique no botão voltar duas vezes para acessar a página anterior à sua. Considerando isso, você precisa adicionar algum código para interromper a propagação de eventos. A maioria dos kits de ferramentas javascript já terá uma função para isso. Por exemplo, o kit de ferramentas dojo usa

dojo.stopEvent(event);

para fazer isso.

linusthe3rd
fonte
9
Gostaria de avisar que, se você usar href="#"o navegador, procurará uma marca de âncora nomeada e, como não a encontrará, fará com que a janela role para o topo da página, algo que talvez não seja perceptível se você já está no topo. Para evitar esse comportamento, use: em href="javascript:;"vez disso.
Albert.torres
1
@ alonso.torres Bom ponto, mas é por isso que mencionei o uso de dojo.stopEvent () - ele interromperá a propagação de eventos / bolhas e o comportamento padrão de clicar na âncora.
linusthe3rd
7
Em vez de StopEvent, porque não basta retornar falso (onclick = "someFunction (e); return false;")
stracktracer
10

A resposta principal é uma prática muito ruim, nunca se deve vincular a um hash vazio, pois isso pode criar problemas no caminho.

O melhor é vincular um manipulador de eventos ao elemento, como muitas outras pessoas declararam, no entanto, <a href="javascript:doStuff();">do stuff</a>funciona perfeitamente em todos os navegadores modernos, e eu o uso extensivamente ao renderizar modelos para evitar a necessidade de religar novamente para cada instância. Em alguns casos, essa abordagem oferece melhor desempenho. YMMV

Outro detalhe interessante ....

onclicke hrefter comportamentos diferentes ao chamar javascript diretamente.

onclickpassará o thiscontexto corretamente, enquanto hrefnão funcionará, ou seja <a href="javascript:doStuff(this)">no context</a>, não funcionará, enquanto <a onclick="javascript:doStuff(this)">no context</a>funcionará.

Sim, eu omiti o href. Embora isso não siga as especificações, ele funcionará em todos os navegadores, embora, idealmente, deva incluir uma href="javascript:void(0);"boa medida

Eduardo
fonte
8

Ter javascript:qualquer atributo que não seja especificamente para scripts é um método desatualizado de HTML. Embora tecnicamente funcione, você ainda está atribuindo propriedades javascript a um atributo que não é script, o que não é uma boa prática. Pode até falhar em navegadores antigos, ou mesmo em alguns modernos (uma postagem no fórum no Google parece indicar que o Opera não gosta de 'javascript:' urls).

Uma prática melhor seria a segunda maneira, de colocar seu javascript no onclickatributo, que será ignorado se nenhuma funcionalidade de script estiver disponível. Coloque um URL válido no campo href (geralmente '#') para fallback para aqueles que não possuem javascript.

zombat
fonte
1
Não vejo como há diferença entre um 'javascript:' href e um '#' href com um atributo onclick. Ambos são igualmente inúteis para navegadores sem o JS ativado.
harto 2/07/2009
2
harto, isso não está realmente correto. '#' é um indicador para um link nomeado, não é um identificador de javascript. É um URL válido e não requer que o Javascript seja reconhecido.
zombat 02/07/2009
8

funcionou para mim usando esta linha de código:

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

Isso funciona

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>
TitusMix
fonte
3
Bem-vindo ao Stack Overflow! Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código. Tente também não sobrecarregar seu código com comentários explicativos, pois isso reduz a legibilidade do código e das explicações!
Adeus StackExchange
2
Este código não funciona. return: false é inválido. Deve ser retornado falso.
hbulens
5

Pessoalmente, acho chato fazer chamadas javascript na tag HREF. Normalmente, não presto muita atenção se algo é ou não um link javascript, e muitas vezes quero abrir as coisas em uma nova janela. Quando tento fazer isso com um desses tipos de links, recebo uma página em branco com nada e javascript na minha barra de localização. No entanto, isso é evitado um pouco usando um onlick.

Pedro
fonte
3

Mais uma coisa que notei ao usar "href" com javascript:

O script no atributo "href" não será executado se a diferença de horário entre 2 cliques for bastante curta.

Por exemplo, tente executar o exemplo a seguir e clique duas vezes (rápido!) Em cada link. O primeiro link será executado apenas uma vez. O segundo link será executado duas vezes.

<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>

Reproduzido no Chrome (clique duplo) e IE11 (com clique triplo). No Chrome, se você clicar rápido o suficiente, poderá fazer 10 cliques e ter apenas 1 execução de função.

Firefox funciona bem.

Kolobok
fonte
3

Primeiro, hrefé melhor incluir o URL, pois permite aos usuários copiar links, abrir em outra guia etc.

Em alguns casos (por exemplo, sites com alterações frequentes de HTML), não é prático vincular links sempre que houver uma atualização.

Método típico de ligação

Link normal:

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

E algo assim para JS:

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

Os benefícios desse método são a separação clara de marcação e comportamento e não precisam repetir as chamadas de função em todos os links.

Método sem vinculação

Se você não deseja vincular todas as vezes, no entanto, pode usar onclick e passar o elemento e o evento, por exemplo:

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

E isso para JS:

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

O benefício desse método é que você pode carregar novos links (por exemplo, via AJAX) sempre que quiser, sem ter que se preocupar em vincular todas as vezes.

jchavannes
fonte
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>   
Andrew
fonte
0

Percebi que o javascript: hrefs não funcionava quando a página foi incorporada ao recurso de página da Web do Outlook, onde uma pasta de email está configurada para mostrar um URL

cristão
fonte