禁用输入框上的选项卡

12

我正在我的应用程序中实施渐进式UI披露模式。使用此模式,我正在禁用下一个元素。因此,根据一个元素的输入,下一个元素将被启用。

但是,我的问题是由于下一个元素被禁用了,从当前元素开始的标签会在到达文档结尾或标签头时丢失焦点。由于渐进式使元素在标签后面启用,所以在这种情况下,下一个元素尚未启用,因此标签已经丢失在文档外部。

因此,我的要求是在禁用的元素上启用标签,并且在移动/平板设备上,单击事件应至少在禁用的元素上注册。请让我知道您对此的看法。


1
你有示例代码吗? - Kalimah
@mac9416 不错的建议,为什么不直接启用按钮并添加一点JavaScript代码,以便根据您想要确保满足的表单条件来防止提交? - benvc
1
@benv 我喜欢这个想法。也许只需将按钮样式设置为禁用即可。 - crenshaw-dev
1
@mac9416 是的,这似乎比覆盖禁用元素的焦点行为更容易。祝你好运。 - benvc
1
请添加示例代码。 - Akrion
显示剩余2条评论
5个回答

6

回答

为了回答这个问题(正如我们在评论中已经讨论过的),禁用的元素不能被聚焦

解决方法

对于那些寻找解决办法的人,以下是一个简化的示例,其中提交按钮看起来是禁用的,并且除非输入包含一些文本(还原“禁用”状态如果输入被清除),否则将防止默认功能,同时仍然保留可聚焦性和单击事件。

const input = document.querySelector('input');
const button = document.querySelector('button');
input.addEventListener('input', (event) => {
  const target = event.currentTarget;
  const next = target.nextElementSibling;
  if (target.value) {
    next.classList.remove('disabled');
  } else {
    next.classList.add('disabled');
  }
});

button.addEventListener('click', (event) => {
  const target = event.currentTarget;
  if (target.classList.contains('disabled')) {
    event.preventDefault();
    console.log('not submitted');
  } else {
    console.log('submitted');
  }
});
button {
  background-color: #fff;
  color: #0d47a1;
  border: 2px solid #0d47a1;
}

button.disabled {
  background-color: #e0e0e0;
  color: #bdbdbd;
  border: 2px solid #bdbdbd;
  cursor: default;
}
    
button.disabled:focus {
  outline: none;
}
<input type="text">
<button class="disabled">Submit</button>


1
我喜欢这个。这可能是我要走的路线。唯一的修改是,我可能会添加 aria-disabled="true" 以及 disabled 类来提高可访问性。 - crenshaw-dev

3

您可以添加一个事件监听器到keydown事件,并像代码片段中一样监听tab键,

document.addEventListener("keydown", keyDown);

function keyDown(e) {
  switch (e.which) {
    case 9:
      var focused = $(document.activeElement);
      var all_inputs = $("input");
      var disabled_inputs = $("input[disabled='disabled']");
      var diff = all_inputs.length - disabled_inputs.length;
      var index = all_inputs.index(focused);
      if (index == diff - 1 && index != -1 && disabled_inputs.length > 0) {
        $(disabled_inputs[0]).removeAttr("disabled").focus();
        e.preventDefault();
      }
      break;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="text" placeholder="this is not disabled!"> <br>
<input type="password" placeholder="this is not either!"> <br>
<input type="button" value="This is!" disabled="disabled"> <br>
<input type="submit" value="This is too!" disabled="disabled">

当您在该元素上按Tab键时,它将被启用。否则不会影响正常行为。我假设您不想在焦点离开后重新禁用该元素。


顺便说一下,如果你想让它只关注于那个位置,以便视图会滚动到那里,那么就保持原样并设置滚动条,虽然我不是 UI 方面的专家,但我认为只要你防止默认行为使其不会滚动到其他地方,这将实现最终用户看到的相同效果。 - DarthCadeus
不幸的是,移除禁用属性是聚焦(测试)的先决条件。我正在考虑“已样式化但实际上未禁用”的路线。手动设置滚动条甚至比样式花招更具侵入性。 - crenshaw-dev
虽然这并非直接回答问题,但如果您只是隐藏下一个元素,会更容易。而且为什么您想让用户专注于已禁用的元素呢? - DarthCadeus
不要使用启用/禁用技巧(测试)。隐藏哪个下一个元素?提交按钮还是下一个可聚焦的元素?我并不是想允许聚焦,而是想防止聚焦到下一个元素(可能会导致不愉快的滚动-请参见链接的测试)。也许我需要处理tab键按下事件并阻止默认行为?不确定是否会产生副作用。 - crenshaw-dev
1
可能就是这样了。通常情况下,无论如何,没有人能够在浏览器输入字段中键入常规制表符。此外,我的意思是下一个可聚焦元素,但如果这是您想要实现的内容,那么防止默认操作就足够了。 - DarthCadeus
显示剩余3条评论

0

根据我的想法,对于下拉框和输入框来说,一个输入事件监听器或更改事件监听器会更适合您的情况。例如:

$(document).on('input','input',function()
{
  $(this).next().prop('disabled',false);
}

或者

$(document).on('change','input',function()
{
  $(this).next().prop('disabled',false);
}

0

在这种情况下,您可以使用tabindex属性。请参考下面的代码,您需要以一种方式更新禁用元素的tabindex,以便在按Tab键时跳过它们。

根据w3schools的说法

tabindex属性指定了元素的制表顺序(当使用“tab”按钮进行导航时)。

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


    <input class="input-1" tabindex="1" value="1">
    <input class="input-2" tabindex="2" value="2">
    <input type="button" onclick="changeTabIndex();" value="change-tab-index">
    <input class="input-3" tabindex="3" value="3">
    <input class="input-4" tabindex="4" value="4">
    <input class="input-5" tabindex="5" value="5">
    <script type="text/javascript">
     function changeTabIndex() {
      $(".input-5").attr("tabindex",4);
      $(".input-4").attr("tabindex",5);
     }
    </script>


0

如果我们有一些代码的话,就更好理解你的问题了。

为此:

我正在应用渐进式UI披露模式。使用该模式,我会禁用下一个元素。因此,基于一个元素的输入,下一个元素将被启用。

您必须先处理第一个元素的事件,然后在回调函数中需要启用/禁用第二个元素,例如:

启用:

$('#firstElement).on('click', function(){ $('#secondElement').removeAttr('disabled') })

禁用:

$('#firstElement).on('click', function(){ $('#secondElement').attr('disabled', 'disabled') })

希望这能帮到您。


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