如何使用纯CSS禁用提交按钮和链接的单击功能?

10
我挑战自己只使用HTML和CSS来创建视觉上动态和交互式的体验(没有Javascript)。到目前为止,我还没有遇到任何需要Javascript才能实现的功能。这个问题可能会有点困难。
我需要防止用户双击

你能否让表单在第一次提交后自动赋予自己一个类? - SIGSTACKFAULT
1
或许默认情况下应该是 pointer-events: all,但在 :active:focus 状态下不是吗?就像在这些状态下设置 pointer-events: none 一样? - Jeremy Harris
可能会将 el:active, el:focuspointer-events 结合使用。 - Paragon512
这段代码能正常工作吗? :active { display:none; // 举个例子} - Mohamad Fazel Hesari
添加了尝试。但在触发点击之前禁用了它。 - Paragon512
请注意:如果您想要防止重复提交,那么必须在服务器端进行处理。没有其他方法。仅使用客户端(CSS/JS)解决方案总是可以被用户绕过(无论是意外还是恶意)。 - RoToRa
2个回答

4

一种想法是在第一次点击后,在元素上方添加一个层来避免第二次点击。

这里有一个基本的想法,我将考虑两次点击之间的持续时间为1秒,您可以缩短它。尝试单击按钮/链接,您会注意到只有在1秒后才能再次单击。

我正在添加一个小叠加层以更好地看到这个技巧。

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


我认为它仍然让我点击按钮两次?我可以看到第二次按钮被按下。 - Paragon512
@Paragon512 用什么浏览器?我在Chrome和Firefox上测试过了。 - Temani Afif
1
@TemaniAfif 当我使用 <a href="#" onclick="console.log('lalala')">点击我</a> 来链接代码的其余部分时,控制台没有任何日志输出。在我看来,这意味着链接没有被点击。 - Aleksandr Belugin
1
看起来测试这个最好的方法是使用<a>标签。我尝试使用提交按钮进行测试,但监视网络检查器很奇怪且不一致。当我点击链接时,它不会触发点击事件。如果您将目标设置为锚点并单击链接,它将禁用链接但不会跳转到锚点。 - Paragon512
@Paragon512 发现了一个解决办法,现在应该没问题了。 - Temani Afif
显示剩余8条评论

0

第一种解决方案

思路是利用radio button状态通过:checked进行修改。我们隐藏radio圆圈,当<a>被选中时,使用pointer-events: none;,对于不同类型的buttons,我们将它们隐藏并显示disabled的按钮。

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>

第二种解决方案

这个适用于链接。思路是使用:target。首先隐藏目标元素。然后当被选中时,使用:target<a>pointer-events: none;

#anchor {
  display: none;
}

#anchor:target {
  display: block;
}

#anchor:target+a {
  pointer-events: none;
}
<div>
  <span id="anchor"></span>
  <a href="#anchor" onclick="console.log('anchor clicked!')">Click the link!</a>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接