il y a des liens avec des actions d'événement onclick
<a href="#" onclick="alert('panic!')">Let's panic</a>
<a href="#" onclick="alert('panic!')" disabled="disabled">I can't panic no more</a>
J'ai besoin d'empêcher l'exécution des actons d'événement sur les liens avec l'attribut désactivé sans supprimer les actions onclick.
$('a[disabled]').click(function(e){
e.stopPropagation();
return false;
});
Ce code ne m'aide pas.
mise à jour Même ce code ne fonctionne pas
<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>
jQuery ne va pas résoudre celui-ci OOTB. Cela peut aider, mais rien de stopPropagation
, stopImmediatePropagation
, preventDefault
, return false
Ne fonctionnera si vous les attachez simplement à l'élément. Vous devez remplacer le gestionnaire de clics de l'élément.
Cependant, vous indiquez dans votre question "sans supprimer les actions onclick" . Vous devez donc remplacer le comportement par défaut au moment où l'événement est déclenché (par opposition à l'approche plus simple consistant simplement à null
à supprimer l'attribut onclick
pour les ancres désactivées):
Voici ce que je veux dire:
<!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>
L'approche consiste à remplacer le gestionnaire de clics en ligne (onclick
) avec une logique préemptive pour détecter le cas où l'ancre est "désactivée" et puis annuler l'événement (avec return false
).
L'avantage est que pour réactiver une ancre, il vous suffit de .removeAttr('disabled')
dessus.
disabled
n'est pas une propriété des ancres. Utilisez quelque chose comme rel='disabled'
au lieu.
$('a[rel="disabled"]').click( function() { return false; } );
Mise à jour:
Ah, bien sûr. Il déclenche toujours le alert
car il est en fait en ligne dans le balisage! Je ne fais jamais ça et je n'ai donc pas remarqué. Retirez ce gestionnaire de clics du balisage et faites-le dans jQuery en premier lieu et vous pourrez alors simplement faire quelque chose comme:
$('a').click( function() {
if( $(this).attr('rel') == 'disabled' ) { return; }
// do stuff here when not disabled
return false; // so your '#' href doesn't get used
} );
Le problème est que jQuery ajoute des événements dans l'ordre. Pour arrêter d'autres événements, les événements que vous devez arrêter doivent venir après votre code d'arrêt. Puisque vous avez du code dans votre clic, vous devrez modifier la commande. Voici ce que je ferais:
<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>
L'avantage est simplement de supprimer/ajouter la classe désactivée à l'aide de jQuery: $('a#whatever').addClass('disabled')
ou de la supprimer $('a#whatever').removeClass('disabled')
et aucun autre nettoyage/configuration n'est requis.
Tous les gestionnaires de clics ajoutés par jQuery semblent se déclencher après ceux ajoutés dans le balisage. Ma solution serait d'appliquer les gestionnaires de clics à l'aide de jQuery au lieu de dans le balisage, mais vous pouvez ne pas avoir suffisamment de contrôle sur le code pour ce faire. Si vous le faites, n'appliquez simplement pas le gestionnaire de clic aux balises d'ancrage avec la classe désactivée (et, oui, j'utiliserais une classe plutôt qu'un attribut inapproprié). Si vous n'avez pas de contrôle sur le balisage, vous souhaiterez peut-être remplacer le gestionnaire de clics à l'aide de jQuery, en le stockant pour une réapplication ultérieure.
$(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;
}
});
});
});
Testé avec:
<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>
J'ai trouvé une solution assez simple pour empêcher les onclicks aujourd'hui, mais en conservant l'action si vous en avez besoin.
<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();
});
Je ne suis pas un grand fan de l'utilisation de "javascript:", mais c'était de loin la solution la plus simple au problème.
J'espère que cela aide!