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.


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>


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.