Éviter que la case à cocher ne coche / ne coche complètement
on m'a demandé de désactiver le" tic-tac " d'une case à cocher. On ne me demande pas de désactiver la case à cocher, mais simplement de désactiver le"tic-tac".
en d'autres termes, un utilisateur pensera qu'une case à cocher peut être cochée, mais qu'elle ne l'est pas. En cliquant sur la case à cocher, un dialogue modal apparaîtra, donnant à l'utilisateur plus d'options pour activer ou désactiver la fonction que la case à cocher représente. Si les options choisies dans la boîte de dialogue cause la fonction soit activée, la case sera cochée.
Maintenant, le vrai problème, c'est que pour un fraction de seconde , vous pouvez voir que la case est cochée.
j'ai essayé une approche comme celle-ci:
<input type='checkbox' onclick='return false' onkeydown='return false' />
$('input[type="checkbox"]').click(function(event) {
event.preventDefault();
alert('Break');
});
si vous lancez ceci, l'alerte apparaîtra, montrant que la tique est visible (l'alerte est juste là pour démontrer qu'elle est toujours cochée, dans la production, l'alerte n'est pas là). Sur certains utilisateurs avec des machines plus lentes et/ou dans les navigateurs avec des rendus lents / javascript, les utilisateurs peuvent voir un clignotement très faible (le clignotement dure parfois une demi-seconde, ce qui est perceptible).
un testeur de mon équipe a signalé ceci comme un défaut et je suis censé le corriger. Je ne suis pas sûr de ce que je peux essayer d'autre pour empêcher la tique dans la case à cocher de clignoter!
9 réponses
meilleure solution que j'ai trouvé:
$('input[type="checkbox"]').click(function(event) {
var $checkbox = $(this);
// Ensures this code runs AFTER the browser handles click however it wants.
setTimeout(function() {
$checkbox.removeAttr('checked');
}, 0);
event.preventDefault();
event.stopPropagation();
});
cet effet ne peut pas être supprimé je le crains. Dès que vous cliquez sur la case à cocher, l'état (et le rendu) est modifié. Ensuite, les gestionnaires d'événements sera appelée. Si vous faites un event.preventDefault()
, la case à cocher sera réinitialisée après tous les manipulateurs sont exécutés. Si votre handler a un long délai d'exécution (facilement testable avec un modal alert()
) et/ou le moteur de rendu repeint avant de redémarrer, la boîte clignotera.
$('input[type="checkbox"]').click(function(event) {
this.checked = false; // reset first
event.preventDefault();
// event.stopPropagation() like in Zoltan's answer would also spare some
// handler execution time, but is no more needed here
// then do the heavy processing:
alert('Break');
});
This solution permettra de réduire le scintillement à un minimum, mais ne peut pas entraver vraiment. Voir la réponse de Thr4wn et RobG pour savoir comment simuler une case à cocher. Je préfère le suivant:
<button id="settings" title="open extended settings">
<img src="default_checkbox.png" />
</button>
document.getElementById("settings").addEventListener("click", function(e) {
var img = this.getElementsByTagName("img")[0]);
openExtendedSettingsDialog(function callbackTick() {
img.src = "checked_checkbox.png";
}, function callbackUntick() {
img.src = "unchecked_checkbox.png";
});
}, false);
De mon point de vue, c'est aussi simple que:
$(this).prop('checked', !$(this).prop('checked'));
Fonctionne à la fois pour les coché et décoché les cases
avec CSS, vous pouvez changer l'image de la case à cocher. Voir http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons / et aussi cases à cocher de style CSS .
Je désactiverais la case à cocher, mais je la remplacerais par une image d'une case à cocher fonctionnelle. De cette façon, la case à cocher n'a pas l'air désactivée, mais ne sera pas cliquable.
envelopper la case à cocher avec un autre élément qui bloque d'une façon ou d'une autre les événements de pointeur (probablement via CSS). Ensuite, manipulez l'événement de clic wrapper au lieu de la case à cocher directement. Cela peut être fait de plusieurs façons, mais voici un exemple relativement simple de mise en œuvre:
$('input[type="checkbox"').parent('.disabled').click( function() {
// Add in whatever functionality you need here
alert('Break');
});
/* Insert an invisible element that covers the checkbox */
.disabled {
position: relative;
}
.disabled::after {
content: "";
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Only wrapped checkboxes are "disabled" -->
<input type="checkbox" />
<span class="disabled"><input type="checkbox" /></span>
<input type="checkbox" />
<span class="disabled"><input type="checkbox" /></span>
<span class="disabled"><input type="checkbox" /></span>
<input type="checkbox" />
Note: Vous pouvez également ajouter les éléments d'enrubannage par programmation, si vous le souhaitez.
me semble que vous utilisez le mauvais élément de l'interface, le plus approprié serait un bouton est désactivé par défaut, mais activé lorsque cette option est disponible. L'image affichée peut être celle que vous voulez.
<button disabled onclick="doSomething();">Some option</button>
lorsque les utilisateurs ont sélectionné cette fonctionnalité, activez le bouton. L'image sur le bouton peut être modifiée par CSS selon qu'elle est activée ou non, ou par la fonction Activer/désactiver.
p.ex.
<script type="text/javascript">
function setOption(el) {
var idMap = {option1:'b0', option2: 'b1'};
document.getElementById(idMap[el.value]).disabled = !el.checked;
}
</script>
<div><p>Select options</p>
<input type="checkbox" onclick="setOption(this);" value="option1"> Option 1
<br>
<input type="checkbox" onclick="setOption(this);" value="option2"> Option 2
<br>
</div>
<div>
<button id="b0" onclick="alert('Select…');" disabled>Option 1 settings</button>
<button id="b1" onclick="alert('Select…');" disabled>Option 2 settings</button>
</div>
Le Event.preventDefault
méthode devrait travailler pour change
, keydown
, et mousedown
événements", mais n'est pas dans mes tests.
ma solution à ce problème dans une extension Mozilla Firefox 53.0 a été de basculer une classe HTML qui a activé/désactivé la déclaration CSS pointer-events: none
appliquée à la case à cocher. Cela s'applique au cas basé sur le curseur, mais pas au cas basé sur la clé. Voir https://www.w3.org/TR/SVG2/interact.html#PointerEventsProp .
j'ai abordé le cas des clés en ajoutant/supprimant un attribut HTML tabindex="-1"
. Voir https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex .
notez que la désactivation de pointer-events
désactivera votre capacité de déclencher les curseurs CSS en vol stationnaire (par exemple, cursor: not-allowed
). Ma case à cocher était déjà enveloppée dans un élément span
, donc je j'ai ajouté une classe HTML à cet élément span
sur lequel j'ai ensuite redirigé ma déclaration CSS cursor
.
notez également que l'ajout d'un attribut tabindex="-1"
supprimera le focus de la case à cocher et non , de sorte qu'il sera nécessaire de le recentrer explicitement en utilisant la méthode HTMLElement.blur()
ou en focalisant un autre élément pour empêcher les entrées basées sur les clés si la case à cocher est l'élément actif au moment où l'attribut est ajouté. Que la case à cocher soit cochée ou non est l'élément focalisé peut être testé avec my_checkbox.isEqualNode(document.activeElement)
.
Il est très important d'utiliser return false
à la fin.
quelque chose comme ça:
$("#checkbox").click((e) => {
e.stopPropagation();
return false;
});