Jak wyłączyć przycisk przesyłania i łącza po kliknięciu w czystym CSS?

9

Rzuciłem sobie wyzwanie, aby stworzyć wizualnie dynamiczną i interaktywną obsługę tylko w HTML i CSS (bez Javascript). Jak dotąd nie spotkałem się z żadną potrzebną funkcją, której nie mogłem zrobić w czystym CSS i HTML. Ten jest może nieco trudniejszy.

Muszę uniemożliwi użytkownikowi podwójne kliknięcie <a>, <input type="submit">i <button>tagów. Zapobiega to podwójnemu przesłaniu formularza lub przypadkowemu wysłaniu 2 żądań GET do adresu URL. Jak można to zrobić w czystym CSS? Nawet jeśli nie możemy ustawić disabledbez JS, powinna istnieć jakaś technika maskowania lub połączenie stylów, które poradzą sobie tutaj w 2020 roku.

Oto prosty przykład próby:

.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>

Niestety powoduje to wyłączenie z jakiegoś powodu faktycznego zdarzenia kliknięcia. Może kotwice nie są najlepszym sposobem na przetestowanie? Będę kontynuował próby.

Paragon512
źródło
czy możesz sprawić, aby formularz dał sobie klasę po przesłaniu go po raz pierwszy?
SIGSTACKFAULT
1
Może pointer-events: alldomyślnie, ale nie w stanach: aktywny lub: fokus? Jak ustawione pointer-events: nonedla tych stanów?
Jeremy Harris
może w el:active, el:focuspołączeniu ze zdarzeniami wskaźnikowymi
Paragon512
czy to działa? : active {display: none; // na przykład}
MD Hesari
Dodano próbę. Wyłączyło to jednak przed uruchomieniem kliknięcia.
Paragon512

Odpowiedzi:

4

Jednym z pomysłów jest posiadanie warstwy, która pojawia się na górze elementu po pierwszym kliknięciu, aby uniknąć drugiego.

Oto podstawowy pomysł, w którym rozważę czas 1spomiędzy dwoma kliknięciami, który możesz zmniejszyć. Spróbuj kliknąć przycisk / link, a zauważysz, że możesz kliknąć ponownie dopiero później 1s.

Dodałem małą nakładkę, aby lepiej zobaczyć sztuczkę

.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
źródło
1
wydaje się, że nie działa z <a>tagiem
Aleksandr Belugin
@AleksandrBelugin działa dobrze, sprawdź aktualizację. Może zrobiłeś coś złego
Temani Afif
Myślę, że nadal pozwala mi kliknąć przycisk 2 razy? Za drugim razem widzę przycisk wciśnięty.
Paragon512
1
@TemaniAfif, gdy robię to, <a href="#" onclick="console.log('lalala')">Click me</a>aby połączyć się z resztą kodu, nic nie loguje się na konsolę. imho oznacza to, że link nie został kliknięty
Aleksandr Belugin
1
Wygląda na to, że najlepszym sposobem na sprawdzenie tego jest <a>tag. Próbowałem testować za pomocą przycisków przesyłania, ale monitorowanie inspektora sieci jest dziwne i niespójne. Kiedy klikam link, nie uruchamia kliknięcia. Jeśli ustawisz cel na kotwicę i klikniesz link, spowoduje to wyłączenie linku, ale nie przejdzie do kotwicy.
Paragon512
0

Pierwsze rozwiązanie

Chodzi o to, aby użyć radio buttonstanu przez :checkeddo modyfikacji. Chowamy radiokoło i gdy :checkeddla <a>marki pointer-events: none;i dla buttonsz różnymi rodzajami je ukrywać i pokazywać disabledte.

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>

Drugie rozwiązanie

Ten pasuje do links. Chodzi o to, aby użyć :target. Targe elementjest najpierw ukryty. Wtedy, gdy jest ukierunkowane wykorzystanie :targetdo pointer-events: none;z <a>.

Aleksandr Belugin
źródło