Qual è la differenza tra i diversi metodi per inserire il codice JavaScript in un <a>?


87

Ho visto i seguenti metodi per inserire codice JavaScript in un <a>tag:

function DoSomething() { ... return false; }
  1. <a href="javascript:;" onClick="return DoSomething();">link</a>
  2. <a href="javascript:DoSomething();">link</a>
  3. <a href="javascript:void(0);" onClick="return DoSomething();">link</a>
  4. <a href="#" onClick="return DoSomething();">link</a>

Comprendo l'idea di provare a inserire un URL valido invece del solo codice JavaScript, nel caso in cui l'utente non abbia JavaScript abilitato. Ma ai fini di questa discussione, devo presumere che JavaScript sia abilitato (non possono accedere senza di esso).

Personalmente mi piace l'opzione 2 in quanto ti consente di vedere cosa verrà eseguito, particolarmente utile durante il debug in cui sono presenti parametri passati alla funzione. L'ho usato un po 'e non ho riscontrato problemi con il browser.

Ho letto che le persone consigliano 4, perché fornisce all'utente un vero link da seguire, ma in realtà # non è "reale". Non andrà assolutamente da nessuna parte.

Ce n'è uno che non è supportato o è davvero pessimo, quando sai che l'utente ha JavaScript abilitato?

Domanda correlata: Href per collegamenti JavaScript: "#" o "javascript: void (0)"? .


Piccolo problema di sintassi: la scelta n. 2 dovrebbe essere - <a href="javascript:DoSomething();"> link </a> senza il "ritorno"
DRosenfeld

Si prega di modificare la risposta accettata in risposta @eyelidlessness. Penso che sia l'approccio migliore, perché ha a cuore la semantica.
Michał Perłakowski

Risposte:


69

Mi piace molto l'articolo sulle best practice Javascript di Matt Kruse . In esso, afferma che utilizzare la hrefsezione per eseguire il codice JavaScript è una cattiva idea. Anche se hai dichiarato che i tuoi utenti devono avere JavaScript abilitato, non c'è motivo per cui non puoi avere una semplice pagina HTML a cui tutti i tuoi link JavaScript possono puntare per la loro hrefsezione nel caso in cui qualcuno disattivi JavaScript dopo l'accesso. Ti incoraggio vivamente a consentire ancora questo meccanismo di riserva. Qualcosa di simile aderirà alle "best practice" e raggiungerà il tuo obiettivo:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

4
come il valore href verrà mostrato all'utente nella barra di stato? (la barra in basso) Prenderò in considerazione l'utilizzo di un collegamento un po 'più intuitivo, ad es. "js.html? doSomething" la pagina può ancora essere html statico. In questo modo l'utente vedrà chiaramente una differenza tra i collegamenti.
Gene

7
Puoi sostituire questo valore con l'attributo title, ad esempio <a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> go </a>
Conspicuous Compiler

Dovrebbe essere buona pratica registrare le richieste nella pagina javascript_required.html e registrare la funzione che ha causato l'errore.
Timo Huovinen

2
Hai pensato alle conseguenze per la SEO?
DanielBlazquez

Javascripttoolbox.com di Matt Kruse sembra essere offline e in vendita.
showdev

10

Perché dovresti farlo quando puoi usare addEventListener/ attachEvent? Se non c'è href-equivalente, non usare un <a>, usa a <button>e modellalo di conseguenza.


9
l'uso di un pulsante invece di un collegamento non è un'opzione fattibile in molti casi.
nickf

2
Perché sembra brutto. È possibile aggiungere un'icona accanto al collegamento. Sono difficili da formattare lo stesso su tutti i browser. E in generale, le persone si spostano sui link anziché sui pulsanti: guarda la maggior parte dello stack over flow.
Darryl Hein,

2
Sembra brutto? Assomiglia a quello che vuoi che assomigli. In effetti, penso che i pulsanti abbiano effettivamente più flessibilità di stile rispetto ai collegamenti, in quanto sono in linea ma possono assumere correttamente il riempimento tra i browser. Tutto ciò che può essere fatto con un collegamento può essere fatto con un pulsante, per quanto riguarda i CSS.
mancanza di palpebre

2
Span non può essere focalizzato sulla tastiera.
bobince

3
E il pulsante è (sussulto) semanticamente corretto. Span è semanticamente privo di significato. Un pulsante è esattamente ciò che l'autore intende utilizzare, semanticamente.
mancanza di palpebre

5

Hai dimenticato un altro metodo:

5: <a href="#" id="myLink">Link</a>

Con il codice JavaScript:

document.getElementById('myLink').onclick = function() {
    // Do stuff.
};

Non posso commentare quale delle opzioni ha il miglior supporto o quale è semanticamente la migliore, ma dirò solo che preferisco di gran lunga questo stile perché separa il tuo contenuto dal tuo codice JavaScript. Mantiene insieme tutto il codice JavaScript, che è molto più facile da mantenere (specialmente se lo stai applicando a molti collegamenti), e puoi persino metterlo in un file esterno che può quindi essere compresso per ridurre le dimensioni del file e memorizzato nella cache dai browser client.


7
Se hai 20 o 30 collegamenti diversi con JS, questo può diventare piuttosto noioso e finire con un sacco di JS.
Darryl Hein,

non è più noioso che guadare HTML per cambiare javascript. ... oppure potresti usare qualcosa come jQuery che può facilmente cambiare gli eventi su più elementi contemporaneamente ... $ ('# menu a'). click (function () {..})
nickf

1
@ JKirchartz Non vedo come sta predicando se ci sono ragioni dietro la risposta. Se leggi la domanda, è davvero un "quale di questi 4 è il migliore", e ho solo fatto notare che c'è un'altra opzione che non aveva considerato.
nickf

Non importa, trololo, quando si sceglie tra ABC e D, non si sceglie E.
JKirchartz

3
@JKirchartz Sì, non credo che tu abbia davvero capito lo scopo di Stack Overflow allora. Se qualcuno chiede "Quale è meglio creare un'app Web in: Cobol o Fortran?" È accettabile dire a quella persona che non ha considerato tutte le possibilità. La domanda chiaramente non è chiedersi "quale di queste quattro cose sia la migliore".
nickf

3
<a href="#" onClick="DoSomething(); return false;">link</a>

Lo farò, oppure:

<a href="#" id = "Link">link</a>
(document.getElementById("Link")).onclick = function() {
    DoSomething();
    return false;
};

Dipende dalla situazione. Per le app più grandi, la seconda è la migliore perché consolida il codice dell'evento.


Se hai 20 o 30 collegamenti diversi con JS, questo può diventare piuttosto noioso e finire con un sacco di JS.
Darryl Hein,

e bug che si insinuano nel tuo codice possono essere MOLTO difficili da correggere. Questi bug appaiono molto facilmente, come evidenziato dal tuo primo esempio. :)
nickf

1

Il metodo n. 2 presenta un errore di sintassi in FF3 e IE7. Preferisco i metodi # 1 e # 3, perché # 4 sporca l'URI con '#' sebbene causi meno digitazione ... Ovviamente, come notato da altre risposte, la soluzione migliore è separare l'html dalla gestione degli eventi.


Metodo n. 2 di cosa? Le domande non rimangono nello stesso ordine di quando le hai viste.
Diodeus - James MacFarlane

Il metodo n. 4 non rovinerà l'URI se ti assicuri di farlo return false. Per questo motivo il metodo n. 4 è probabilmente il migliore (di quelli elencati).
Már Örlygsson

2
@Diodeus, credo che Pier si riferisse all'elenco numerato all'interno della domanda , che in effetti è stato lì da quando la domanda è stata pubblicata in primo luogo.
mancanza di palpebre

1

Una differenza che ho notato tra questo:

<a class="actor" href="javascript:act1()">Click me</a>

e questo:

<a class="actor" onclick="act1();">Click me</a>

è che se in entrambi i casi hai:

<script>$('.actor').click(act2);</script>

quindi per il primo esempio, act2verrà eseguito prima act1e nel secondo esempio, sarà il contrario.


1

Solo browser moderni

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }
    doc.addEventListener('click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault();
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

Cross-browser

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var cb_addEventListener = function(obj, evt, fnc) {
        // W3C model
        if (obj.addEventListener) {
            obj.addEventListener(evt, fnc, false);
            return true;
        } 
        // Microsoft model
        else if (obj.attachEvent) {
            return obj.attachEvent('on' + evt, fnc);
        }
        // Browser don't support W3C or MSFT model, go on with traditional
        else {
            evt = 'on'+evt;
            if(typeof obj[evt] === 'function'){
                // Object already has a function on traditional
                // Let's wrap it with our own function inside another function
                fnc = (function(f1,f2){
                    return function(){
                        f1.apply(this,arguments);
                        f2.apply(this,arguments);
                    }
                })(obj[evt], fnc);
            }
            obj[evt] = fnc;
            return true;
        }
        return false;
    };
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }

    cb_addEventListener(doc, 'click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault ? e.preventDefault() : e.returnValue = false;
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

Puoi eseguirlo prima che il documento sia pronto, facendo clic sui pulsanti funzionerà perché alleghiamo l'evento al documento.

Fonti:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.