2009-11-18 15 views
29

gibt es einige Links mit Onclick-Ereignisse AktionenPrevent Aktion OnClick mit jQuery

<a href="#" onclick="alert('panic!')">Let's panic</a> 
<a href="#" onclick="alert('panic!')" disabled="disabled">I can't panic no more</a> 

ich brauche, ohne zu entfernen Onclick Aktionen Ereignis Actons Ausführung auf Links mit deaktiviert Attribute zu verhindern.

$('a[disabled]').click(function(e){ 
    e.stopPropagation(); 
    return false; 
}); 

Dieser Code hilft mir nicht.

Update Auch dieser Code funktioniert nicht

<html><head><script type='text/javascript' src='jquery-1.3.2.js'></script></head> 
<body> 
<a href='#' onclick="alert('HA-ha!')" disabled="disabled" class="disabled">TEST</a> 
<script type="text/javascript"> 
    $('a[disabled], a.disabled').click(function(e){ 
     console.log('override?'); 
     e.stopImmediatePropagation();   
      e.preventDefault(); 
     e.stopPropagation(); 
     return false;  
    }); 
</script> 
</body></html> 
+1

Ihr gesamter jQuery-Code sollte in ein '$ (document) .ready (function() {... code here ...}) eingeschlossen werden;' Dies in Verbindung mit dem Entfernen des 'disabled' Tags von Ihrem Markup und Selector sollten Dinge zum Laufen bringen. – rfunduk

+0

'return false;' vs. 'e.preventDefault();' vs 'e.stopPropagation();' Diskussion gefunden hier: http://stackoverflow.com/questions/1357118/javascript-event-preventdefault-vs-return -false –

Antwort

52

jQuery ist nicht diesen OOTB gehen zu lösen. Es kann helfen, aber keiner von stopPropagation, , preventDefault, return false funktioniert, wenn Sie sie einfach an das Element anhängen. Sie müssen überschreiben Click-Handler des Elements.

Allerdings geben Sie in Ihrer Frage "ohne Entfernen von onclick Aktionen". So müssen Sie das Standardverhalten außer Kraft zu setzen an dem Punkt des Ereignis ausgelöst wird, (im Gegensatz zu dem Reiniger Ansatz einfach null ing über das onclick Attribut für Behinderte Anker):

Hier ist, was ich meine:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<title>Disable clicks</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
</head> 
<body> 
    <a href="#" onclick="alert('panic!')">Let's panic</a> 
    <a href="#" onclick="alert('panic!')" disabled="disabled">I can't panic no more</a> 

    <script> 
    $('a[onclick]').each(function(){ 
    $(this).data('onclick', this.onclick); 

    this.onclick = function(event) { 
     if($(this).attr('disabled')) { // HERE 
     return false; 
     }; 

     $(this).data('onclick').call(this, event || window.event); 
    }; 
    }); 
    </script> 
</body> 
</html> 

Demo here.

der Ansatz ist die Inline-Click-Handler (onclick) mit präemptiven Logik außer Kraft zu setzen, den Fall zu fangen, wo der Anker „gesperrt“ ist und dann Abbruch der Veranstaltung (mit return false).

Der Vorteil dort ist, dass Sie einfach wieder einen Anker .removeAttr('disabled') darauf aktivieren.

+0

Schöne, saubere Lösung! Ist das 'Ereignis || window.event notwendig, da jQuery die Browser bereits normalisiert und das 'event'-Objekt die bereinigte Version ist, wenn der Code sie aufruft? –

+4

@dcneiner: Ja, es ist erforderlich. Beachten Sie, dass wir uns gerade in einem Inline-Event-Handler befinden ('onclick'), den der Browser aufruft, * not * ein Handler, den jQuery normalisiert und aufruft. –

+0

Großartig! Danke für die Lösung und Erklärung. Genau das, was ich brauche. –

7

disabled keine Eigenschaft des Dübels ist. Verwenden Sie stattdessen etwas wie rel='disabled'.

$('a[rel="disabled"]').click(function() { return false; }); 

aktualisieren:

Ah, natürlich. Es feuert immer noch die alert, weil es tatsächlich in der Markup inline ist! Ich tue das nie und habe es auch nicht bemerkt. Nehmen Sie den Klick-Handler aus dem Markup und tut es in jQuery an erster Stelle und so kann man dann tun nur so etwas wie:

$('a').click(function() { 
    if($(this).attr('rel') == 'disabled') { return; } 
    // do stuff here when not disabled 
    return false; // so your '#' href doesn't get used 
}); 
+1

+1 Ich habe nicht einmal den schlechten Selektor bemerkt – Matt

+0

Ja, jQuery _should_ in der Lage sein zu machen 'a [deaktiviert =" deaktiviert "]' Arbeit, aber IMO, das ist eine schlechte Idee. Stick mit gültigem Markup :) – rfunduk

+0

Wie auch immer, ich habe versucht zu verhindern, dass eine Klasse mit dem Namen deaktiviert verwendet. Es tut immer noch nichts. –

1

jeden Klick-Handler hinzugefügt von jQuery scheint nach dem in der Markierung hinzugefügt, um Feuer . Meine Lösung wäre, die Click-Handler mit jQuery statt in der Markup-Funktion zu verwenden, aber Sie haben möglicherweise nicht genügend Kontrolle über den Code, um dies zu tun. Wenn Sie dies tun, wenden Sie einfach nicht den Click-Handler an, um Tags mit deaktivierter Klasse zu verankern (und ja, ich würde eher eine Klasse als ein unangemessenes Attribut verwenden). Wenn Sie keine Kontrolle über das Markup haben, sollten Sie den Click-Handler mit jQuery ersetzen und für eine spätere erneute Anwendung speichern.

$(function() { 
     $('a.disabled').each(function() { 
     var $this = $(this); 
     var click = $this.attr('onclick'); 
     if (click) { 
      $this.data('click',click); 
      // add return false to prevent default action 
      $this[0].onclick = function() { return false; }; 
     } 
     }); 

     $('#restoreClick').click(function() { 
      $('a.disabled').each(function() { 
       var $this = $(this); 
       $this.removeClass('disabled'); 
       var click = $this.data('click'); 
       if (click) { 
        $this[0].onclick = click; 
       } 
      }); 
     }); 
    }); 

Getestet mit:

<div> 
    <a href="#" onclick="alert('panic!')">Let's panic</a> 
    <a href="#" onclick="alert('panic!')" class="disabled">I can't panic no more</a> 
</div> 
<div> 
    <input type="button" id="restoreClick" value="Restore" /> 
</div> 
4

Das Problem ist, dass jQuery Ereignisse in der Reihenfolge hinzufügt. Um andere Ereignisse zu stoppen, müssen die Ereignisse, die Sie anhalten müssen, nach Ihrem Stoppcode kommen. Da Sie bei Ihrem Klick Code haben, müssen Sie die Reihenfolge ändern. Dies ist, was ich tun würde:

<a href='#' onclick="alert('HA-ha!')" class="disabled">TEST</a> 
<a href='#' onclick="alert('HA-ha!')">TEST</a> 
<script type="text/javascript"> 
    $('a').each(function(){ 
     // Cache event 
     var existing_event = this.onclick; 

     // Remove the event from the link 
     this.onclick = null; 

     // Add a check in for the class disabled 
     $(this).click(function(e){ 
      if($(this).hasClass('disabled')){ 
       e.stopImmediatePropagation(); 
       e.preventDefault(); 
      }     
     }); 

     // Reattach your original onclick, but now in the correct order 
     // if it was set in the first place 
     if(existing_event) $(this).click(existing_event); 
    }); 
</script> 

Die Leistung wird nur entfernen/hinzufügen, die deaktivierte Klasse mit jQuery: $('a#whatever').addClass('disabled') oder entfernen Sie es $('a#whatever').removeClass('disabled') und keine andere Bereinigungen/Einrichtung erforderlich ist.

0

Ich fand eine ziemlich einfache Lösung, um onclicks heute zu verhindern, aber halte die Aktion, wenn du sie brauchst.

<a href="javascript:alert('panic!')" >Let's panic</a> 
<a href="javascript:alert('panic!')" disabled="disabled">I can't panic no more</a> 

$('a').click(function(e){ 
    if($(this).attr('disabled')) e.preventDefault(); 
}); 

Ich bin kein großer Fan von "Javascript:", aber das war bei weitem die einfachste Lösung für das Problem.

Hoffe es hilft!

+0

'Ich bin kein großer Fan von" Javascript: ", aber das war bei weitem die einfachste Lösung für das Problem. Sie bevorzugen die anderen Client-Seite Skriptsprachen tun ya? – user1167442

+3

Ich liebe JavaScript, aber ich bevorzuge es, Javascript inline mit der "javascript:" Syntax zu verwenden. "javascript: alert ('panic!')" <- Beispiel. Die erste Voraussetzung einer Smart-Ass Bemerkung ist, dass es "smart";) – MrBojangles

+0

ist es in der Tat ... – user1167442