"Javascript: void (0);" vs "return false" vs "verhindernDefault ()"

75

Wenn ich möchte, dass ein Link nichts anderes tut, als nur auf Javascript-Aktionen zu reagieren, wie kann ich am besten vermeiden, dass der Link zum oberen Rand der Seite rollt?
Ich kenne verschiedene Möglichkeiten, sie scheinen alle gut zu funktionieren:

<a href="javascript:void(0)">Hello</a>

oder

<a id="hello" href="#">Hello</a>
<script type="text/javascript>
  $(document).ready(function() {
    $("#toto").click(function(){
      //...
      return false;
    });
  });
</script>

und sogar :

<a id="hello" href="#">Hello</a>
<script type="text/javascript>
  $(document).ready(function() {
    $("#toto").click(function(event){
      event.preventDefault();          
      //...
    });
  });
</script>

Hast du eine Präferenz? Warum ? unter welchen Bedingungen?

PS: In den obigen Beispielen wird natürlich davon ausgegangen, dass Sie jquery verwenden, aber es gibt Entsprechungen für Mootools oder Prototypen.

Mike
quelle

Antworten:

68

Bindung:

  • javascript: URLs sind ein Horror, der jederzeit vermieden werden sollte.
  • Inline-Event-Handler-Attribute sind ebenfalls nicht brillant, aber für eine schnelle Entwicklung / Tests in Ordnung.
  • Das Binden aus dem Skript, wobei das Markup sauber bleibt, wird normalerweise als bewährte Methode angesehen. jQuery unterstützt dies, aber es gibt keinen Grund, warum Sie dies in keiner Bibliothek oder in einfachem JS tun können.

Antworten:

  • In jQuery return falsebedeutet beides preventDefaultund stopPropagation, daher ist die Bedeutung unterschiedlich, wenn Sie sich für übergeordnete Elemente interessieren, die die Ereignisbenachrichtigung erhalten.
  • jQuery ist es hier versteckt , aber preventDefault/ stopPropagationhaben in der Regel in IE unterschiedlich geschrieben werden ( returnValue/ cancelBubble).

Jedoch:

  • Sie haben einen Link, der kein Link ist. Es verbindet sich nirgendwo; Es ist eine Aktion. <a>ist nicht wirklich das ideale Markup dafür. Es wird schief gehen, wenn jemand versucht, mit der mittleren Maustaste darauf zu klicken oder es zu Lesezeichen oder anderen Vorteilen eines Links hinzuzufügen.
  • In Fällen, in denen es wirklich auf etwas verweist, z. B. wenn es ein anderes Element auf der Seite öffnet / schließt, stellen Sie den Link so ein, dass er auf etwas verweist, #thatelementsidund verwenden Sie unauffälliges Scripting, um die Element-ID aus dem Linknamen abzurufen. Sie können auch das location.hashLaden eines Dokuments abhören, um dieses Element zu öffnen, sodass der Link in anderen Kontexten nützlich wird.
  • Andernfalls ist es für etwas, das nur eine Aktion ist, am besten, es als eine zu markieren: <input type="button">oder <button type="button">. Sie können es mit CSS so gestalten, dass es wie ein Link anstelle einer Schaltfläche aussieht, wenn Sie möchten.
  • Es gibt jedoch einige Aspekte des Schaltflächenstils, die Sie in IE und Firefox nicht ganz loswerden können. Es ist normalerweise nicht signifikant, aber wenn Sie wirklich absolute visuelle Kontrolle benötigen, besteht ein Kompromiss darin, <span>stattdessen ein zu verwenden. Sie können eine tabindexEigenschaft hinzufügen , um sie in den meisten Browsern für die Tastatur zugänglich zu machen, obwohl dies nicht richtig standardisiert ist. Sie können auch Tastendrücke wie Leertaste oder Eingabetaste erkennen, um sie zu aktivieren. Dies ist etwas unbefriedigend, aber immer noch sehr beliebt (SO, zum einen, macht es so).
  • Eine andere Möglichkeit ist <input type="image">. Dies hat die Zugänglichkeitsvorteile der Schaltfläche mit vollständiger visueller Kontrolle, jedoch nur für reine Bildschaltflächen.
Bobince
quelle
2
+1, aber ich bin nicht einverstanden mit "Inline-Event-Handler-Attribute sind auch nicht brillant". Sofern Sie nicht mehrere Handler benötigen, sind Tag-Attribute, wie sie onclickbei weitem die einfachste und sauberste Methode zum Anhängen eines Ereignishandlers an ein Element sind.
Casablanca
Danke für die vollständige Antwort. Ich denke nie wirklich so ... aber es scheint mir jetzt klar, dass es kein Link sein sollte. Ich werde die oben genannten Techniken Input / Span ausprobieren und sehen, was besser passt. @casablanca Ich stimme nicht wirklich zu, ich habe das erste Beispiel geschrieben, aber ich benutze es nie wirklich. Genauso wie ich es hasse, CSS in meinem HTML zu sehen, denke ich wirklich, dass Javascript-Code immer unauffällig sein und in externen Dateien bleiben sollte.
Mike
6
Ich stimme voll und ganz zu "Inline-Event-Handler-Attribute sind auch nicht brillant". Sie mögen für das schnelle Prototyping einfach sein, aber wenn Sie diesen zweiten Handler hinzufügen müssen, werden Sie schnell inkonsistent, wie Sie Handler anhängen, und Inkonsistenz führt zu Fehlern. Die Verknüpfung sollte von selbst funktionieren, wie Bobince feststellt, und die Verbesserung, um ausgefallene Leistungen zu erbringen, sollte Teil des Controllers sein , der vom Modell und der Ansicht
Stephen P
3
Stephen P - stimme vollkommen zu, außer mit der Implikation, dass MVC 'das Richtige' ist :) Es ist nur eine Möglichkeit, Dinge zu organisieren (zugegebenermaßen beliebt) und hat seine Nachteile wie alles andere.
sje397
1
Wenn Sie nie mehr als eine Listener-Funktion für ein bestimmtes Ereignis und Element benötigen und Ihren eigenen Verstand kennen, ist an den Attributen der Ereignishandler nichts auszusetzen. Tatsächlich haben sie gegenüber jeder anderen Methode der Ereignisbindung den Vorteil, sofort zu arbeiten, ohne darauf warten zu müssen, dass ein anderes Skript geladen und die Bindung ausgeführt wird.
Tim Down
18

Der einzige Vorteil, den ich mir vorstellen kann, javascript:void(0)ist, dass es auch von den ältesten Browsern unterstützt wird. Trotzdem würde ich einen der anderen unauffälligen Ansätze verwenden, die Sie erwähnt haben:

  • Für die meisten Anwendungen event.preventDefault()und return falsekann austauschbar verwendet werden.
  • event.preventDefault()verhindert, dass die Seite wie gewünscht neu geladen wird, ermöglicht jedoch, dass das Klickereignis zum übergeordneten Element sprudelt. Wenn Sie das Sprudeln stoppen möchten, können Sie es in Verbindung mit verwenden event.stopPropagation.
  • return false verhindert außerdem, dass das Ereignis zum Elternteil sprudelt.

Ich sage im ersten Punkt oben "austauschbar", weil es uns die meiste Zeit egal ist, ob ein Ereignis zu den Eltern sprudelt oder nicht. Wenn jedoch Sie benötigen wir einige Feinabstimmung, sollten wir Punkte zwei und drei in Betracht ziehen.

Betrachten Sie das folgende Beispiel:

<div>Here is some text <a href="www.google.com">Click!</a></div>​

$("a").click(function(e) {
    e.preventDefault();
});

$("div").click(function() {
    $(this).css("border", "1px solid red");
});
​

Durch Klicken auf den Anker wird verhindert, dass die Standardaktion des Ereignisses ausgelöst wird, sodass der Browser nicht zu www.google.com umleitet. Das Ereignis wird jedoch immer noch "sprudeln" und das Klickereignis des Divs auslösen, wodurch ein Rahmen um das Ereignis hinzugefügt wird. Add e.stopPropagation() or just return false und das Klickereignis des Div wird nicht ausgelöst. Hier können Sie sich damit anlegen: http://jsfiddle.net/cMKsN/1/

karim79
quelle
Aus Interesse: event.precentdefault()Ist der Aufruf an der Spitze Ihres Handlers wirksam, wenn danach in Ihrem Handlercode eine Ausnahme auftritt?
sje397
@ sje397 Ja, wenn Sie haben event.preventDefault(); someFunction();und etwas mit someFunction () kaputt geht, wird das Standardereignis immer noch gestoppt.
Robert
Nun, Sie haben einen Punkt in der Browser-Unterstützung, aber auch eine gute Erklärung für beide Welten, stoppen Sie die Verbreitung und verhindern Sie Default +1
Leo
2

Dreamweaver verwendet standardmäßig einen netten kleinen Trick, den ich verwendet habe.

<a href='javascript:;'></a>

Es ist klein, es stolpert nicht und verankert sich und es ist bibliotheksunabhängig.

Whit
quelle
Ich denke, das ist das gleiche Beispiel wie mein erstes. Der Browser wartet auf eine URL und in beiden Fällen wird der Ausdruck mit null oder undefiniert (null == undefiniert) ausgewertet.
Mike
@ Mike: Es wird tatsächlich undefinedin beiden Fällen ausgewertet . nullist ein gültiger JavaScript-Wert und nicht identisch mit undefined.
Casablanca
@casablanca: es gilt immer noch, dass (null == undefined) === true, (null === undefined) === false.
Weiglt
Schön! Genau das brauchte ich!
Nick
1

Ich bevorzuge die Verwendung return false, da dies dem Benutzer die Möglichkeit gibt, diese Aktion, wie hier gezeigt, im Quirksmode fortzusetzen:

http://www.quirksmode.org/js/events_early.html#default

Es ist einfach, es ist alt, aber es funktioniert gut, browserübergreifend, unabhängig von der Version von Javascript.

James Black
quelle
1

event.preventDefault()und return false;sind eine Sache - sie weisen den Browser an, die Standardaktion für das Ereignis nicht zu verarbeiten (in diesem Fall navigieren Sie zur href des Ankertags, auf das geklickt wurde). href=javascript:und seine Art sind etwas anderes - sie bewirken, dass die Standardaktion "nichts tun" lautet.

Es ist eine Frage des Stils. Möchten Sie Ihre gesamte Arbeit mit onclick erledigen oder möchten Sie in der Lage sein, Aktionen sowohl mit onclick als auch mit href auszuführen und sich auf die Funktionen des Browsers zu verlassen, um zwischen beiden zu modulieren?

Dan Davies Brackett
quelle
2
event.preventDefault()und return false;sind nicht eine Sache
Timo Huovinen
1

Ich verwende href="javascript:void(0)"den Link gerne, um #an den Anfang der Seite zu springen. Dies kann tatsächlich passieren, wenn Ihr jQuery-Ereignis aus irgendeinem Grund nicht geladen wird, z. B. wenn jQuery nicht geladen werden kann.

Ich verwende event.preventDefault();es auch, da es dem Link nicht folgt, selbst wenn ein Fehler auftritt, bevor false zurückgegeben wird. zum Beispiel:

HTML:

<a id="link" href="http://www.google.com">Test</a>

jQuery Beispiel 1:

$("#link").click(
    function(){
        alert("Hi");
        invalidCode();
        return false;
    }
);

jQuery Beispiel 2:

$("#link").click(
    function(event){
        event.preventDefault();
        alert("Hi");
        invalidCode();
        return false;
    }
);

Da invalidCode();wird ein Fehler return falsenie erreicht und wenn jQuery Beispiel 1 verwendet wird, wird der Benutzer zu Google weitergeleitet, während dies in jQuery Beispiel 2 nicht der Fall ist.

Adam
quelle
1

Ich denke, dass ich auch Javascript gesehen habe:; Während sich das Web entwickelt, ist es schwierig, die verfügbaren Tricks im Auge zu behalten. Dabei geht es hauptsächlich um die Zugänglichkeit (neben Javascript: void (0);), und nur eine kleine Korrektur ist kein Javascript: void (0). aber Javascript: void (0); was bedeutet, nichts zu tun, als falsch zurückzugeben; obwohl nicht sicher, ob Javascript: return false; macht das gleiche ..

Ich benutze immer und würde vorschlagen, Javascript zu verwenden: void (0); aus ein paar gründen .. meiner bescheidenen meinung nach natürlich.

1.) Ich benutze es wegen der gleichen Person, die oben erwähnt wurde. Href = "#" ist nicht angemessen, da es bedeuten könnte, nach oben zu gehen, und selbst in diesem Fall wäre '#top' für diesen Fall angemessener. Dies kann aber auch etwas anderes in Ihrem Code auslösen, das # (Hashes) verwendet. Ein weiterer Grund besteht darin, Konflikte mit anderem Javascript zu vermeiden, das möglicherweise # verwendet. Und ich neige dazu, dies zu suchen, wenn ich zum Beispiel ein Plugin verwende, und sie sofort zu ersetzen. Href = '#' to href = 'javascript: void (0);' oder href = 'Javascript:;'

2.) Wenn ich eine Funktion für eine Gruppe bestimmter Anchor-Tags wiederverwenden möchte, kann ich sie mit dem Selektor für jedes Attribut aufrufen, ohne mir Gedanken über das Erkennen des Klickereignisses und das Verhindern der Standardaktion machen zu müssen, und ich mache es, ohne darüber nachzudenken es als Entwicklungspräferenz.

3.) In den meisten Fällen, wenn Sie Linkbuilding mit Javascript durchführen: void (0); versucht, einen Link so zu erstellen, dass er nicht wie der alte href = rel = nofollow verfolgt wird, um zu vermeiden, dass Links indiziert werden, bei denen es sich um Aktionen handelt. Ich bin mir da nicht so sicher, nur weil ich gehört habe, dass Crawler und Roboter jetzt sogar Flash lesen können. Es würde mich also nicht wundern, wenn sie Javascript-Links lesen können

4.) Unter Bezugnahme auf 2.) können Sie auf eine Klasse wie zielen und vergessen, die Standardaktion für Klickereignisse zu verhindern, indem Sie href = "javascript: void (0);" und dann die Klasse direkt vom Selektor in der jQuery-Funktion aus anvisieren.

        jQuery(function($)
        {
            //from the rel
            $('a[rel="-your-rel-id"]') ... off('click').on('click',function()

            //from the class
            $('a.-the-class') ... off('click').on('click',function()

            //from the id

            $('a#-the-id').off('click').on('click',function()
            {
            --do something with this link
        });

}); 

Ich fühle mich in der Klasse eher wohl, als Sie es immer tun können ...

$ (eine # -Ihre-ID) .hasClass (-Ihre Klasse-)

oder eine andere interessante Kombination und beeinflussen viele Links. Ich werde also wirklich nicht empfehlen, das A nur als Selektor zu verwenden.

Normalerweise sehe ich hier Folgendes:

  jQuery(function($)
        {
            //from the rel
            $('a[rel="-your-rel-id"]').on('click',function(event)
            //do something
            //prevent the click as is passed to the function as an event
            event.preventDefault();
        });

});
Jean Paul AKA el_vete
quelle
0

Ich würde lieber kein JavaScript in das hrefeinfügen, weil es nicht dafür gedacht ist. Ich bevorzuge so etwas

<a href="#" onclick="return handler();">Link</a>
casablanca
quelle