Comment désactiver le bouton de soumission et les liens au clic en CSS pur?

9

Je me suis mis au défi de créer une expérience visuellement dynamique et interactive en HTML et CSS uniquement (sans Javascript). Jusqu'à présent, je n'ai rencontré aucune fonctionnalité dont j'avais besoin que je ne pouvais pas faire en CSS et HTML pur. Celui-ci est peut-être un peu plus difficile.

Je dois empêcher l'utilisateur d' un double-clic <a>, <input type="submit">et les <button>tags. C'est pour les empêcher de soumettre deux fois un formulaire ou de faire accidentellement 2 requêtes GET à une URL. Comment cela peut-il être fait en CSS pur? Même si nous ne pouvons pas définir disabledsans JS, il devrait y avoir une technique de masquage ou une combinaison de styles qui peuvent le gérer ici en 2020.

Voici un exemple simple d'une tentative:

.clicky:focus{
  display: none;
  pointer-events: none;
}
<a href="#down" class="clicky">test</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p id="down">target</p>

Malheureusement, cela le désactive avant que l'événement de clic réel ne soit déclenché pour une raison quelconque. Peut-être que les ancres ne sont pas la meilleure façon de tester? Je continuerai de faire de nouvelles tentatives.

Paragon512
la source
pouvez-vous faire en sorte que le formulaire se donne une classe après avoir été soumis la première fois?
SIGSTACKFAULT
1
Peut-être pointer-events: allpar défaut, mais pas dans les états: actif ou: focus? Comme défini pointer-events: nonepour ces États?
Jeremy Harris
peut être el:active, el:focuscombiné avec des événements de pointeur
Paragon512
Est-ce que ça marche? : active {affichage: aucun; // par exemple}
MD Hesari
Tentative ajoutée. Il l'a cependant désactivé avant de tirer le clic.
Paragon512

Réponses:

4

Une idée est d'avoir un calque qui vient sur le dessus de l'élément après le premier clic pour éviter le second.

Voici une idée de base où je considérerai une durée 1scomprise entre deux clics que vous pourrez diminuer. Essayez de cliquer sur le bouton / lien et vous remarquerez que vous ne pouvez cliquer à nouveau qu'après 1s.

J'ajoute une petite superposition pour mieux voir l'astuce

.button {
  position:relative;
  display:inline-block;
}
.button span{
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:100%;
  z-index:-1;
  animation:overlay 1s 0s; /* Update this value to adjust the duration */
  transition:0s 2s; /* not this one! this one need to be at least equal to the above or bigger*/
}


.button *:active + span {
  animation:none;
  bottom:0;
  transition:0s 0s;
}

@keyframes overlay {
  0%,100% {
    z-index:999;
    background:rgba(255,0,0,0.2); /* To illustrate */
  }
}
<div class="button">
  <button>Click me</button>
  <span></span>
</div>

<div class="button">
  <a href="#" onclick="console.log('clicked !')">Click me</a>
  <span></span>
</div>

Temani Afif
la source
1
il ne semble pas fonctionner avec le <a>tag
Aleksandr Belugin
@AleksandrBelugin ça fonctionne bien, vérifiez la mise à jour. Peut-être que vous avez fait quelque chose de mal
Temani Afif
Je pense que ça me laisse quand même cliquer 2 fois sur le bouton? Je peux voir le bouton enfoncer la deuxième fois.
Paragon512
1
@TemaniAfif quand je fais cela <a href="#" onclick="console.log('lalala')">Click me</a>pour établir un lien avec le reste du code, rien ne se connecte à la console. à mon humble avis, le lien n'est pas cliqué
Aleksandr Belugin
1
Il semble que la meilleure façon de tester cela soit avec la <a>balise. J'ai essayé de tester avec des boutons de soumission, mais la surveillance de l'inspecteur de réseau est étrange et incohérente. Lorsque je clique sur le lien, il ne déclenche pas le clic. Si vous définissez une cible sur une ancre et cliquez sur le lien, cela désactivera le lien mais ne passera pas à l'ancre.
Paragon512
0

La première solution

L'idée est d'utiliser radio buttonstate by :checkedpour effectuer des modifications. Nous masquons le radiocercle et lorsque :checkedpour <a>faire pointer-events: none;et pour buttonsdifférents types, nous les masquons et les disabledaffichons.

div {
  margin: 10px;
}

#radio0, .my-checkbox {
  position: absolute;
  height: 0;
  width: 0;
  opacity: 0;
}

#radio0 + a label {
  cursor: pointer;
}

#radio0:checked+a {
  pointer-events: none;
}

.btn-one,
.btn-two {
  padding: 0;
}

.btn-one>label,
.btn-two>label {
  padding: 1px 6px;
}

.my-checkbox:checked+.btn-one {
  display: none;
}

.btn-two {
  display: none;
}

.my-checkbox:checked+.btn-one+.btn-two {
  display: inline-block;
}
<div>
  <input id="radio0" type="radio" onclick="console.log('radio0 clicked!')">
  <a href="#">
    <label for="radio0">
        Click the link!
      </label>
  </a>
</div>

<div>
  <input type="radio" id="radio1" class="my-checkbox">
  <button type="button" class="btn-one" onclick="console.log('radio1 clicked!')">
      <label for="radio1">Click the button!</label>
    </button>
  <button type="button" class="btn-two" onclick="console.log('radio1 NOT clicked!')" disabled>
        <label for="radio1">Click the button!</label>
      </button>
</div>

<div>
  <input type="radio" id="radio2" class="my-checkbox">
  <button type="submit" class="btn-one" onclick="console.log('radio2 clicked!')">
    <label for="radio2">Submit!</label>
  </button>
  <button type="submit" class="btn-two" onclick="console.log('radio2 NOT clicked!')" disabled>
      <label for="radio2">Submit!</label>
    </button>
</div>

La deuxième solution

Celui-ci convient pour links. L'idée est d'utiliser :target. Targe elementest d'abord caché. Puis , quand est ciblé l' utilisation :targetà pointer-events: none;des <a>.

Aleksandr Belugin
la source