如何使用JavaScript全局禁用页面中除所有表单之外的tab键?
我正在制作一个单页应用程序,将于下周发布,面向一个相当大的客户,并将在一个相当大的活动中上线,在那之前还有很多事情要完成 有100多个“页面”都加载在一个700px 600px的窗口中,我不久前就知道你可以在页面/部分中使用tab键,这反过来会破坏应用程序,因为它会将焦点转移到隐藏的屏幕外元素,因此,我禁用了整个应用程序的tab键 但现在有几个地方,我们有一个表单,其中有一些输入字段,您在填写表单时无法通过制表符进行切换。这真是个麻烦事 我需要这样做,以便您可以通过制表符通过表单字段,但只有表单字段。我为表单设置了tabindex属性,并尝试启用“输入”选项卡,但在不导致应用程序跳转到隐藏部分的情况下无法使其工作 这是我需要更改的函数,它将禁用tab键,表单中的输入到输入字段除外如何使用JavaScript全局禁用页面中除所有表单之外的tab键?,javascript,Javascript,我正在制作一个单页应用程序,将于下周发布,面向一个相当大的客户,并将在一个相当大的活动中上线,在那之前还有很多事情要完成 有100多个“页面”都加载在一个700px 600px的窗口中,我不久前就知道你可以在页面/部分中使用tab键,这反过来会破坏应用程序,因为它会将焦点转移到隐藏的屏幕外元素,因此,我禁用了整个应用程序的tab键 但现在有几个地方,我们有一个表单,其中有一些输入字段,您在填写表单时无法通过制表符进行切换。这真是个麻烦事 我需要这样做,以便您可以通过制表符通过表单字段,但只有表单
window.onkeydown = function(e) {
if (e.keyCode === tab) {
return false;
}
}
我试着这么做,但是obv不起作用,哈哈
$('input').keydown(function(e) {
if (e.keyCode === tab) {
return true;
}
});
谢谢:)您是否尝试过在所有您不想使用tab键的元素上设置
tabIndex=“-1”
?我认为这是一个更好的解决方案
否则,在密钥处理程序函数中,测试event.target
(或IE中的event.srcmelement
),查看事件是否源自表单元素。您似乎正在使用jQuery,因此可以将“allowTab”类仅分配给表单中的字段,然后执行以下操作:
$(document).keydown(function(e) {
if (!$(e.target).hasClass("allowTab"))
return false;
});
或
我们要做的是确定下一行是什么输入,然后跳到它 可能需要一些优化,但它可以工作。这原本是为了跳过非表单元素。如果愿意,您可以添加选择器以不跳过。此外,您可以为
Shift+Tab
行为添加逻辑(可能在Tab逻辑之前)
显然,它仍将根据某些元素在源代码中的显示方式来遍历这些元素。但是,为什么不从DOM中删除这些隐藏的元素,而是使用。这样,你就不会有在屏幕外元素之间来回循环的痛苦。我对@Joseph发布的答案做了一些修正,可以在表单的输入中移动+制表符,这样你就可以反转方向。以前,当我第一次必须找到一种方法来做这件事时,这对我来说是一件非常烦人的事情,直到现在,我都没有时间再浪费在寻找一个完整的解决方案上。给你
$(function() {
// gather all inputs of selected types
var inputs = $('input, textarea, select, button'), inputTo;
// bind on keydown
inputs.on('keydown', function(e) {
// if we pressed the tab
if (e.keyCode == 9 || e.which == 9) {
// prevent default tab action
e.preventDefault();
if (e.shiftKey) {
// get previous input based on the current input
inputTo = inputs.get(inputs.index(this) - 1);
} else {
// get next input based on the current input
inputTo = inputs.get(inputs.index(this) + 1);
}
// move focus to inputTo, otherwise focus first input
if (inputTo) {
inputTo.focus();
} else {
inputs[0].focus();
}
}
});
});
演示它的工作情况我希望OP只需要为当前“屏幕”中的字段设置一个
tabIndex
>-1,并且应该是可导航的,其他所有内容都应该是-1。@RobG-当然。这就是我第一句话的意思。当“屏幕”改变时,很容易(特别是因为他似乎正在使用jQuery)更改选项卡索引。我的主要观点是使用tabIndex
,而不是试图取消tab键。有几十个元素需要tabIndex=-1。我还应该提到这样一个事实:我们正在根据您所导航到的上下文在容器中克隆和交换html代码的整个部分。这是一件非常复杂的事情,但它会产生一个问题,即在任何给定上下文中,只要元素位于DOM中,就需要该代码可用。这并不总是一个案例,可以运行时,它的工作…对不起,我想我只是不明白你的页面结构。我认为,由于您使用的是jQuery,因此可以使用一行代码轻松地为所有(适当的)元素设置tabindex。然后,当然,当您显示表单时,您知道可以将其元素的tabindex设置回0?nnnnnn-我不认为能够只显示一两行是问题所在。可能只需按一次键/按下文档上的任何侦听器即可。如果按tab键来自应允许它的元素,请允许它。否则取消它。支持所需的只是一个元素列表(ID、类、数组成员等),这些元素应该允许当前页面“上下文”的选项卡导航。这不会跳过隐藏的输入,或问题中提到的设置屏幕外的输入,并且它会跳过链接,这样,如果您不(或不能)使用该页面,您就无法使用该页面使用鼠标或其他定点设备,同时(虽然很容易修复),它只向前循环,打破了默认的shift tab行为。如果要重用这些元素,为什么不删除这些屏幕外元素,或者至少使用DOM片段或克隆来存储对它的一些引用呢,到目前为止,在应用程序的每个上下文中使用表单字段时(在包含表单的面板设置函数中),这些字段应该是可选项卡的。代码需要存在于所有包含表单的设置函数中,因为在函数运行之前,它们不存在于DOM中,并且当上下文更改时,它们会从DOM中删除,因此有必要将其放在包含表单的上下文中。谢谢:)我发现虽然这种方法有效,但它不能处理通过字段shift+tab的反向tab。如果不是因为我不得不不断地测试和重新测试,我做了很多次这种形式的东西,它最终肯定会出现在我身上。所以,一旦我写了这个shift+tab部分来真正模拟tab键,我会把它贴在这里。你还打算按照你在评论中的指示发布你的解决方案吗?实际上我从来没有找到过解决方案。但是,刚才看到了这条评论,并提出了一个完整的解决方案,用于在表单上进行tabbing和shift+tabbing,并将其发布在下面。
$(document).ready(function() {
//gather all inputs of selected types
var inputs = $('input, textarea, select, button');
//bind on keydown
inputs.on('keydown', function(e) {
//if we pressed the tab
if (e.keyCode == 9 || e.which == 9) {
//prevent default tab action
e.preventDefault();
//get next input based on the current input we left off
var nextInput = inputs.get(inputs.index(this) + 1);
//if we have a next input, go to it. or go back
if (nextInput) {
nextInput.focus();
}
else{
inputs[0].focus();
}
}
});
});
$(function() {
// gather all inputs of selected types
var inputs = $('input, textarea, select, button'), inputTo;
// bind on keydown
inputs.on('keydown', function(e) {
// if we pressed the tab
if (e.keyCode == 9 || e.which == 9) {
// prevent default tab action
e.preventDefault();
if (e.shiftKey) {
// get previous input based on the current input
inputTo = inputs.get(inputs.index(this) - 1);
} else {
// get next input based on the current input
inputTo = inputs.get(inputs.index(this) + 1);
}
// move focus to inputTo, otherwise focus first input
if (inputTo) {
inputTo.focus();
} else {
inputs[0].focus();
}
}
});
});