2011-01-04 19 views
9

Korzystając z jQuery, nie zmieniając atrybutu danego przycisku bez zmiany atrybutu disabled, wyłącz wszystkie zdarzenia kliknięcia dla niego.Jak tymczasowo wyłączyć zdarzenia kliknięcia przycisku bez jego całkowitego wyłączenia?

Myślałem o odzyskaniu obsługi zdarzeń kliknięcia, rozwiązaniu ich i przechowywaniu (powiedzmy, używając data()).

Następnie mogę ponownie je powiązać po ponownym włączeniu przycisku.

+3

Możesz zrewidować swoje podejście - jeśli chcesz przycisk nie działa , wyłącz to. Oznacza to wyraźnie, że przycisk jest wyłączony. To znacznie prostsze, prostsze i bardziej spójne niż obejście domyślnego zachowania. Dlaczego nie chcesz wyłączać przycisku? –

+0

Ponieważ, AFAIK, wyłączone przyciski nie mogą być stylizowane. – Ovesh

Odpowiedz

16

nie trudne do zrobienia, ponieważ jQuery już przechowuje wszystkie swoje programy obsługi zdarzeń jako data() na samym elemencie. Możesz uzyskać (i modyfikować) ten obiekt przez .data().events.

Spróbuj$("#portalLink a").data().events.click = nullw konsoli teraz wyłączyć „Stack Exchange Network” listy rozwijanej w lewym górnym rogu tej strony.

Teraz można łatwo zapisać odniesienie do koparki z:

events._click = events.click; 
events.click = null; 

a następnie przywrócić je za pomocą:

events.click = events._click; 
events._click = null; 

zauważyć, że nie wyłącza zdarzenia, które są związane poprzez .delegate() lub .live(), ponieważ działają na zasadzie propagacji/propagacji zdarzeń. Aby wyłączyć te, jak również, po prostu związać nowy program obsługi, który blokuje rozmnażanie się do elementów przodków:

events._click = events.click; 
events.click = null; 
// Block .live() and .delegate() 
$("#el").click(function (e) { 
    e.stopPropagation(); 
}); 

Ty nawet nie trzeba rozwiązać tę funkcję bloker kiedy nadszedł czas, aby umożliwić teleskopowe ponownie, ponieważ events.click = events._click zastąpi funkcja po prostu związana ze wszystkimi starymi modułami obsługi.

+1

Tego rodzaju podejście może być problematyczne. Po pierwsze, myślę, że przeczytałem gdzieś, że to zachowanie nie jest obsługiwane w nowych wersjach jQuery. Ale nawet jeśli to nie jest prawda, nie jest to udokumentowane zachowanie, więc nie mogę na nim polegać w przyszłych wersjach jQuery. – Ovesh

+1

@Ovesh, Odkładając na bok, myślę, że Javascript jest jednym z języków, prawdopodobnie ze względu na jego dynamiczną naturę, de facto "open source" (nigdy kompilowany, tylko czasami zminiaturyzowany) i historię niezgodności przeglądarek, gdzie jest mniejsze zainteresowanie ukrywaniem/ochrona szczegółów implementacji. Dopóki ryzyko jest zrozumiałe i nie ma lepszej alternatywy, wtedy możesz swobodnie nurkować, modyfikować prototypy, nadpisywać funkcje i ogólnie ... hakować;) –

+0

Uzgodnione. Przyjmuję odpowiedź, ponieważ prawdopodobnie nie ma lepszego rozwiązania. – Ovesh

0

To jest droga. Jeśli onclick określony jako atrybut można przełączyć atrybut busing

$(button_element).attr('click', ''); 

i

$(button_element).attr('click', 'do_the_regular_action()'); 
+0

Załóżmy, że nie znam wszystkich procedur obsługi zdarzeń przypisanych do elementu. I może być ich więcej. – Ovesh

+0

w takim przypadku moje podejście nie zadziała – Thariama

0

Można użyć unbind i bind

$('#control').unbind('click');

i

$('#control').bind('click', NameOfFunctionToCall);

+0

Nie sądzę, że to odpowiada na pytanie OP (choć mógłbym się mylić). Z ich dźwięków może istnieć wiele programów do obsługi kliknięć, a on może nie być w stanie uzyskać odniesienia do obsługi dla powiązania (np. Funkcji anonimowej lub funkcji w innym zakresie). –

+0

Zgadza się. Zobacz mój komentarz do @Thariama. – Ovesh

3

Oto jeszcze jeden sposób:

$("#myButton").click(function() { 
    if ($(this).attr("temp_disable") == "disabled") { 
     //nothing to do, temporarily disabled... 
    } 
    else { 
     alert("You clicked me!"); 
    } 
}); 

Do "wyłączyć" go przez 10 sekund:

$("#myButton").attr("temp_disable", "disabled"); 
window.setTimeout(function() { $("#myButton").attr("temp_disable", ""); }, 10000); 

żywo przypadek testowy: http://jsfiddle.net/yahavbr/ByM6h/

+0

Tak właśnie zrobiłem. Ale problem polega na tym, że musi on zostać dodany do każdego zdefiniowanego programu obsługi. Z punktu widzenia projektu nie jest to dobre rozwiązanie, ponieważ niektóre zdarzenia mogą być dodawane przez kod, który nie jest pod moją kontrolą. – Ovesh

+1

@Jeszcze jedynym sposobem na zrobienie tego "globalnie" oprócz naprawdę wyłączenia przycisku jest zmiana go w coś innego, np. 'div', który wygląda tylko jak przycisk, a następnie zmienia go z powrotem na przycisk po upływie czasu - miejmy nadzieję, że programy obsługi zdarzeń zostaną zachowane, należy je najpierw sprawdzić. –

+0

To całkiem niezły pomysł. Można go zastąpić stylowym włączonym przyciskiem (bez żadnych zdarzeń kliknięcia) i zachować oryginalny przycisk za pomocą 'danych()'. Następnie wymień oryginalny przycisk z powrotem. – Ovesh

0

będę rozszerzać na odpowiedź (ów) oferowanych przez Barry i Thariama ... i myślę, że będzie spełniać sprzeciw Ovesh za:

Możesz dodać obszaru nazw do wiązania to wydarzenie.Dzięki temu możesz odwoływać się do tego określonego wiązania zdarzeń później, bez kolizji z innymi powiązaniami. Myślę, że to jest czystsze niż zaakceptowana odpowiedź ... (Aby być uczciwym, może nie było to dostępne w jQuery w czasie oryginalnego pytania).

// A generic click handler: 
$('.myButton').click(function() { ... }); 

// A namespaced click handler: 
$('.myButton').bind('click.someSituation', function() { ... }); 

// Later you can unbind only the handler you want by using the namespace: 
$('.myButton').unbind('click.someSituation'); 

// The default click handler still works. 
+0

Sądzę, że powinienem był wyjaśnić to pytanie. Mogą występować zdarzenia z wieloma kliknięciami, z których nie wszystkie są związane moim kodem. To rozwiązanie nie jest wystarczająco ogólne. – Ovesh

+0

W moim przykładzie ogólny .click() jest zdarzeniem związanym z innym kodem. Nazwane spacjami .bind (kliknij ...) jest w twoim kodzie. Możesz usunąć powiązaną obsługę obsługi kliknięć bez wpływu na inne moduły obsługi kliknięć. –

+0

Ah, ale pytanie brzmi, chcę wyłączyć * wszystkie * kliknij wydarzenia na nim. – Ovesh

0

Zamiast robić to coś Zastosowanie rdzenia JavaScript, żeby wykonać to zadanie np Zobacz następujący przykład.

function MakeSaveDisabled(flg) { 
    if (flg != null) { 
     $(".btnpost").each(function() { 
      this.removeAttribute("disabled"); 
      if (this.hasAttribute("oclickevt")) { 
       this.setAttribute("onclick", this.getAttribute("oclickevt")); 
      } 
     }); 
    } 
    else { 
     $(".btnpost").each(function() { 
      this.setAttribute("disabled", "true"); 
      if (this.getAttribute("onclick") != null) { 
       this.setAttribute("oclickevt", this.getAttribute("onclick")); 
      } 
      this.removeAttribute("onclick"); 
     }); 
    } 
} 

Zapisz funkcję javascript w tymczasowym atrybucie i powiąż go, gdy jest to wymagane.

1

Wszystkie odpowiedzi są tu już nieaktualne - jak jQuery 1.7 należy użyć .off() jak wyjaśniono on the official jQuery site

<!doctype html> 
 
<html lang="en"> 
 
<head> 
 
    <meta charset="utf-8"> 
 
    <title>off demo</title> 
 
    <style> 
 
    button { 
 
    margin: 5px; 
 
    } 
 
    button#theone { 
 
    color: red; 
 
    background: yellow; 
 
    } 
 
    </style> 
 
    <script src="https://code.jquery.com/jquery-1.10.2.js"></script> 
 
</head> 
 
<body> 
 
    
 
<button id="theone">Does nothing...</button> 
 
<button id="bind">Add Click</button> 
 
<button id="unbind">Remove Click</button> 
 
<div style="display:none;">Click!</div> 
 
    
 
<script> 
 
function flash() { 
 
    $("div").show().fadeOut("slow"); 
 
} 
 
$("#bind").click(function() { 
 
    $("body") 
 
    .on("click", "#theone", flash) 
 
    .find("#theone") 
 
     .text("Can Click!"); 
 
}); 
 
$("#unbind").click(function() { 
 
    $("body") 
 
    .off("click", "#theone", flash) 
 
    .find("#theone") 
 
     .text("Does nothing..."); 
 
}); 
 
</script> 
 
    
 
</body> 
 
</html>

+1

Zgodziłbym się z tym, ale chciałbym, aby ten przykład był najpierw edytowany w celu wywołania off() bez argumentów, aby pokazać, jak usuwa on wszystkie dołączone zdarzenia (bez potrzeby utrzymywania odniesienia do nich). To bardziej odpowiadałoby na pierwotne pytanie. – Ovesh

Powiązane problemy