JavaScript-Funktion in href vs. onclick

474

Ich möchte eine einfache JavaScript-Funktion mit einem Klick ohne Umleitung ausführen.

Gibt es einen Unterschied oder Vorteil zwischen dem Einfügen des JavaScript-Aufrufs in das hrefAttribut (wie folgt:

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

) vs. in das onclickAttribut einfügen (an das onclickEreignis binden )?

SkunkSpinner
quelle
5
Diese Frage wurde bereits zuvor besprochen: stackoverflow.com/questions/245868/…
SolutionYogi

Antworten:

276

Das Setzen des Onclicks innerhalb der href würde diejenigen beleidigen, die stark an die Trennung von Inhalten von Verhalten / Handeln glauben. Das Argument ist, dass sich Ihr HTML-Inhalt ausschließlich auf den Inhalt konzentrieren sollte, nicht auf die Präsentation oder das Verhalten.

Heutzutage besteht der typische Pfad darin, eine Javascript-Bibliothek (z. B. jquery) zu verwenden und mithilfe dieser Bibliothek einen Ereignishandler zu erstellen. Es würde ungefähr so ​​aussehen:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );
Parand
quelle
1
Oder Mootools, Prototypen, Dojo ... oder einfach nur Javascript, aber das wäre viel mehr Code, aber die Übung wert.
Ryan Florence
15
Wenn Sie mit dem Ereignisobjekt nichts zu tun haben, ist einfaches Javascript ziemlich einfach. Holen Sie sich den DOM-Knoten mit obj = document.getElementById () und setzen Sie dann obj.onclick = foo
Matt Bridges
1
Was ist mit der Trennung von Inhalten, wenn die <a href> beispielsweise im laufenden Betrieb in einem Popup-Fenster generiert wird und Sie dennoch ein spezielles Klickverhalten benötigen?
Serge
6
Aber war die Frage nicht nach dem Unterschied zwischen dem Inline-Einfügen des JS-Anrufs und dem Inline- hrefEinfügen onclick? Angenommen, Sie würden es aus irgendeinem Grund inline stellen, welchen sollten Sie verwenden? (In der Praxis würde ich tun, was Sie vorgeschlagen haben, aber Sie scheinen den Unterschied zwischen den beiden Attributen übersprungen zu haben.)
nnnnnn
1
Ich würde mich nur dafür einsetzen, den Funktionsaufruf inline zu setzen, anstatt ein Onclick-Ereignis für den Link zu haben, wenn Sie dynamisch Links auf der Seite erstellen, die alle dieselbe Funktion aufrufen, aber möglicherweise keine eindeutigen IDs haben. Ich habe ein Webformular, in dem der Benutzer Elemente hinzufügen und entfernen kann, und ich setze den Klick in die href der Links innerhalb der dynamisch erstellten Divs, damit ich schneller mit der Verarbeitung des Skripts beginnen kann, anstatt etwas weniger Spezifisches wie eine relative ID oder zu verwenden Klassenname.
MistyDawn
976

Schlecht:

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

gut:

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

besser:

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

noch besser 1:

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

noch besser 2:

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

Warum besser? weil return falseverhindert, dass der Browser dem Link folgt

Beste:

Verwenden Sie jQuery oder ein ähnliches Framework, um den onclick-Handler anhand der ID des Elements anzuhängen.

$('#myLink').click(function(){ MyFunction(); return false; });
demp
quelle
21
Es würde eine andere Lösung geben, die am besten geeignet wäre, wenn sie hrefnicht #auf einen tatsächlichen Link für die noJS-Browser eingestellt wäre.
helly0d
6
Was ist, wenn ich Ihnen sage, dass nur der erste (schlechte) in allen Browsern mit Mittelklick gleich (richtig) funktioniert?
Vloxxity
14
Was ist schlecht an <a id="myLink" href="javascript:MyFunction();">?
Vaddadi Kartick
6
Nur meine bescheidenen 5 Cent: "Die beste" Option wäre, Schaltflächen für Klicks zu verwenden (Onclick-Ereignisse?) Und Anker mit ihren Hrefs zu belassen, was ihre ursprüngliche Designabsicht war: Anker für Links zu anderen Seiten zu sein.
Nidalpres
4
Die On-Click-Bindung mit Javascript hat einen Nachteil: Wenn Sie später jemand anderem sein Formular debuggen, ist es wirklich schwierig zu finden, wo und welche Art von Javascript an dieses Element bindet.
Maarten Kieft
69

In Bezug auf Javascript besteht ein Unterschied darin, dass das thisSchlüsselwort im onclickHandler auf das DOM-Element verweist, dessen onclickAttribut es ist (in diesem Fall das <a>Element), während sich thisdas hrefAttribut auf das windowObjekt bezieht .

Wenn in Bezug auf die Darstellung ein hrefAttribut in einem Link fehlt (dh <a onclick="[...]">), zeigen Browser standardmäßig den textCursor (und nicht den häufig gewünschten pointerCursor) an, da er den <a>als Anker und nicht als Link behandelt.

In Bezug auf das Verhalten unterstützt hrefder Browser beim Festlegen einer Aktion durch Navigation über normalerweise das Öffnen dieser Aktion hrefin einem separaten Fenster über eine Verknüpfung oder ein Kontextmenü. Dies ist nicht möglich, wenn eine Aktion nur über angegeben wird onclick.


Wenn Sie jedoch fragen, wie Sie am besten dynamische Aktionen durch Klicken auf ein DOM-Objekt erzielen können, ist das Anhängen eines Ereignisses mit Javascript, das vom Inhalt des Dokuments getrennt ist, der beste Weg. Sie können dies auf verschiedene Arten tun. Ein üblicher Weg ist die Verwendung einer Javascript-Bibliothek wie jQuery, um ein Ereignis zu binden:

<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>
Adam
quelle
9
Vielen Dank, dass Sie meinen Verdacht bestätigt haben, dass "dies" in "href" und "onclick" anders ist.
joonas.fi
17

ich benutze

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

Ein langer Weg, aber es erledigt den Job. Verwenden Sie einen A-Stil, um zu vereinfachen, dann wird es:

<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style> 
<a nohref onClick="alert('Hello World')">HERE</a>
Clif Collins
quelle
10
+1 Wirklich toll! :-) Ich hatte noch nie von nohrefAttribut gehört. Dies ist die logischste / eleganteste Art, mit solchen Javascript-Aktionen umzugehen. Dies ist kompatibel mit FF12 und IE8. Deshalb werde ich alle meine href="JavaScript:void(0);"durch ersetzen nohref. Vielen Dank. Prost.
Olibre
7
Es wird von großen Browsern nicht unterstützt. Warum sollten wir dies verwenden? w3schools.com/tags/att_area_nohref.asp
hetaoblog
11
nohrefist ein Teil von areaTag, nicht a! Ihr Beispiel ist das gleiche wie<a onClick="alert('Hello World')">HERE</a>
nZeus
6
Nur ein weiteres "Mach diese Warnung nicht". Dies ist völlig unüblich und ein schlechter Rat. nohrefexistiert nicht auf einem aTag.
Colin 't Hart
11

Zusätzlich zu allen hier wird die href in der Statusleiste des Browsers angezeigt und nicht auf. Ich denke, es ist nicht benutzerfreundlich, dort Javascript-Code anzuzeigen.

Kamarey
quelle
10

Der beste Weg, dies zu tun, ist mit:

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

Das Problem ist, dass dadurch am Ende der URL der Seite im Browser ein Hash (#) hinzugefügt wird, sodass der Benutzer zweimal auf die Schaltfläche "Zurück" klicken muss, um zur Seite vor Ihrer zu gelangen. In Anbetracht dessen müssen Sie Code hinzufügen, um die Ereignisausbreitung zu stoppen. Die meisten Javascript-Toolkits haben bereits eine Funktion dafür. Zum Beispiel verwendet das Dojo-Toolkit

dojo.stopEvent(event);

um dies zu tun.

linusthe3rd
quelle
9
Ich möchte Sie warnen, dass, wenn Sie href="#"den Browser verwenden, nach einem benannten Ankertag gesucht wird und das Fenster zum Seitenanfang scrollen kann, was möglicherweise nicht auffällt, wenn der Browser nicht gefunden wird du bist schon oben Um dieses Verhalten zu vermeiden, verwenden Sie href="javascript:;"stattdessen:
Alonso.Torres
1
@ alonso.torres Guter Punkt, aber deshalb habe ich die Verwendung von dojo.stopEvent () erwähnt - es stoppt die Weitergabe / das Sprudeln von Ereignissen und das Standardverhalten beim Klicken auf den Anker.
Linusthe3rd
7
Anstelle von stopEvent, warum nicht einfach false zurückgeben (onclick = "someFunction (e); return false;")
stracktracer
10

Die beste Antwort ist eine sehr schlechte Praxis. Man sollte niemals einen Link zu einem leeren Hash erstellen, da dies später zu Problemen führen kann.

Am besten binden Sie einen Ereignishandler an das Element, wie zahlreiche andere angegeben haben. Er <a href="javascript:doStuff();">do stuff</a>funktioniert jedoch in jedem modernen Browser einwandfrei. Ich verwende ihn häufig beim Rendern von Vorlagen, um zu vermeiden, dass für jede Instanz erneut gebunden werden muss. In einigen Fällen bietet dieser Ansatz eine bessere Leistung. YMMV

Ein weiteres interessantes Leckerbissen ....

onclick& hrefhaben unterschiedliche Verhaltensweisen beim direkten Aufruf von Javascript.

onclickwird den thisKontext korrekt übergeben, wohingegen hrefnicht oder mit anderen Worten <a href="javascript:doStuff(this)">no context</a>nicht funktionieren wird, wohingegen <a onclick="javascript:doStuff(this)">no context</a>wird.

Ja, ich habe das weggelassen href. Dies entspricht zwar nicht der Spezifikation, funktioniert jedoch in allen Browsern, sollte jedoch im Idealfall ein href="javascript:void(0);"gutes Maß enthalten

Eduardo
quelle
8

Das Vorhandensein javascript:eines Attributs, das nicht speziell für die Skripterstellung vorgesehen ist, ist eine veraltete HTML-Methode. Obwohl dies technisch funktioniert, weisen Sie einem Nicht-Skript-Attribut immer noch Javascript-Eigenschaften zu, was keine gute Vorgehensweise ist. Es kann sogar in alten oder sogar in modernen Browsern fehlschlagen (ein gegoogelter Forumsbeitrag scheint darauf hinzudeuten, dass Opera 'javascript:' URLs nicht mag).

Eine bessere Vorgehensweise wäre die zweite Möglichkeit, Ihr Javascript in das onclickAttribut einzufügen , das ignoriert wird, wenn keine Skriptfunktion verfügbar ist. Fügen Sie eine gültige URL in das href-Feld (normalerweise '#') ein, um auf diejenigen zurückzugreifen, die kein Javascript haben.

Zombat
quelle
1
Ich sehe keinen Unterschied zwischen einem 'Javascript:' href und einem '#' href mit einem onclick-Attribut. Beide sind für Browser ohne aktiviertes JS gleichermaßen nutzlos.
Harto
2
Harto, das stimmt eigentlich nicht. '#' ist ein Indikator für einen benannten Link, es ist keine Javascript-Kennung. Es ist eine gültige URL und erfordert nicht, dass Javascript erkannt wird.
Zombat
8

Bei dieser Codezeile hat es funktioniert:

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

Das funktioniert

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>
TitusMix
quelle
3
Willkommen bei Stack Overflow! Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch, Ihren Code nicht mit erklärenden Kommentaren zu überfüllen, da dies die Lesbarkeit sowohl des Codes als auch der Erklärungen beeinträchtigt!
Auf Wiedersehen StackExchange
2
Dieser Code funktioniert nicht. return: false ist ungültig. Es sollte false zurückgegeben werden.
Hbulens
5

Persönlich finde ich es ärgerlich, Javascript-Aufrufe in das HREF-Tag zu setzen. Normalerweise achte ich nicht wirklich darauf, ob etwas ein Javascript-Link ist oder nicht, und möchte oft Dinge in einem neuen Fenster öffnen. Wenn ich dies mit einer dieser Arten von Links versuche, wird eine leere Seite mit nichts darauf und Javascript in meiner Adressleiste angezeigt. Dies wird jedoch durch einen Onlick ein wenig umgangen.

Peter
quelle
3

Eine weitere Sache, die mir bei der Verwendung von "href" mit Javascript aufgefallen ist:

Das Skript im Attribut "href" wird nicht ausgeführt, wenn der Zeitunterschied zwischen zwei Klicks recht kurz war.

Versuchen Sie beispielsweise, das folgende Beispiel auszuführen, und doppelklicken Sie (schnell!) Auf jeden Link. Der erste Link wird nur einmal ausgeführt. Der zweite Link wird zweimal ausgeführt.

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

Wiedergabe in Chrome (Doppelklick) und IE11 (mit Dreifachklick). Wenn Sie in Chrome schnell genug klicken, können Sie 10 Klicks ausführen und nur 1 Funktion ausführen.

Firefox funktioniert einwandfrei.

Kolobok
quelle
3

Erstens ist es am hrefbesten , die URL zu haben, da Benutzer damit Links kopieren, in einem anderen Tab öffnen usw. können.

In einigen Fällen (z. B. Websites mit häufigen HTML-Änderungen) ist es nicht praktisch, bei jedem Update Links zu binden.

Typische Bindungsmethode

Normaler Link:

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

Und so etwas für JS:

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

Die Vorteile dieser Methode sind die saubere Trennung von Markup und Verhalten und müssen nicht die Funktionsaufrufe in jedem Link wiederholen.

Keine Bindungsmethode

Wenn Sie jedoch nicht jedes Mal binden möchten, können Sie onclick verwenden und das Element und das Ereignis übergeben, z.

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

Und das für JS:

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

Der Vorteil dieser Methode besteht darin, dass Sie jederzeit neue Links (z. B. über AJAX) laden können, ohne sich jedes Mal um das Binden kümmern zu müssen.

jchavannes
quelle
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
quelle
0

Ich habe festgestellt, dass Javascript: hrefs nicht funktioniert hat, als die Seite in die Webseitenfunktion von Outlook eingebettet war, in der ein E-Mail-Ordner so eingestellt ist, dass stattdessen eine URL angezeigt wird

Christian
quelle