将焦点从最后一个元素循环到第一个表单元素反之亦然
我使用 malsup 的表单插件创建了一个表单,其中它在输入更改时提交。我已经设置了 jQuery 脚本来索引下拉菜单和可见输入,并使用该索引来确定选项卡的 keydown 是否应将焦点移动到下一个元素或第一个元素,同样使用 shift+tab keydown。但是,它并没有像我希望的那样将焦点从选项卡按键上的最后一个元素移动到第一个元素,而是将焦点移动到第二个元素。如何将其更改为将焦点循环到实际的第一个和最后一个元素?这是我的表单的实时链接: http://www.presspound.org/calculator /ajax/sample.php。感谢任何试图提供帮助的人。这是我的脚本:
$(document).ready(function() {
var options = {
target: '#c_main',
success: setFocus
};
$('#calculator').live('submit', function() {
$(this).ajaxSubmit(options);
return false;
});
$(this).focusin(function(event) {
var shiftDown = false;
$('input, select').each(function (i) {
$(this).data('initial', $(this).val());
});
$('input, select').keyup(function(event) {
if (event.keyCode==16) {
shiftDown = false;
$('#shiftCatch').val(shiftDown);
}
});
$('input, select').keydown(function(event) {
if (event.keyCode==16) {
shiftDown = true;
$('#shiftCatch').val(shiftDown);
}
if (event.keyCode==13) {
$('#captured').val(event.target.id);
} else if (event.keyCode==9 && shiftDown==false) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var nextEl = fields.eq(index+1).attr('id');
var firstEl = fields.eq(0).attr('id');
var focusEl = '#'+firstEl;
if (index>-1 && (index+1)<fields.length) {
$('#captured').val(nextEl);
} else if(index+1>=fields.length) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(firstEl);
} else {
event.preventDefault();
$(focusEl).focus();
}
}
return false;
});
} else if (event.keyCode==9 && shiftDown==true) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var prevEl = fields.eq(index-1).attr('id');
var lastEl = fields.eq(fields.length-1).attr('id');
var focusEl = '#'+lastEl;
if (index<fields.length && (index-1)>-1) {
$('#captured').val(prevEl);
} else if (index==0) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(lastEl);
} else {
event.preventDefault();
$(focusEl).select();
}
}
return false;
});
}
});
});
}); 函数设置焦点(){ 与 (文档.计算器) var recap = document.getElementById(recaptured.value); 如果(重述!=null){ 设置超时(函数(){ if (recap.getAttribute('type')=='text') { 回顾一下。选择(); } 别的 { 回顾一下。焦点(); } }, 100); } }
编辑#1:我对代码做了一些小的更改,这使我更接近于脚本的预期功能。但是,我只对与焦点相关的代码进行了一项更改:我尝试在按下最后一个元素时禁用 tab 键(以及第一个元素上的 shift+tab 键),以尝试强制将焦点放在我想要的元素,而不是像以前那样跳过它。这是我添加的代码:
$(this).one('keydown', function (event) {
return !(event.keyCode==9 && shiftDown==true);
});
这种有效。页面加载后,如果用户在最后一个元素上按 Tab 键而不更改其值,则焦点将设置到第二个元素。但是,用户第二次在最后一个元素上按 Tab 键而不更改其值,以及此后的每次,焦点将设置为第一个元素,正如我希望的那样。
编辑 #2:我用使用 event.preventDefault() 的代码替换了编辑 #1 中的代码,效果更好。而如果用户在第一个元素中按下 Shift+Tab 键,焦点就会按预期移动到最后一个元素。但是,如果用户继续按住 Shift 键并再次按 Tab,焦点将返回到第一个元素。如果用户继续按住 Shift 键并点击 Tab,焦点将移回到最后一个元素。焦点将在第一个和最后一个元素之间来回移动,直到用户抬起 Shift 键。仅按 Tab 时不会出现此问题。这是新的代码片段:
event.preventDefault();
$(focusEl).focus();
I have created a form with malsup's Form Plugin wherein it submits on change of the inputs. I have set up my jQuery script to index drop down menus and visible inputs, and uses that index to determine whether keydown of tab should move focus to the next element or the first element, and likewise with shift+tab keydown. However, instead of moving focus to the first element from the last element on tab keydown like I would like it to, it moves focus to the second element. How can I change it to cycle focus to the actual first and last elements? Here is a live link to my form: http://www.presspound.org/calculator/ajax/sample.php. Thanks to anyone that tries to help. Here is my script:
$(document).ready(function() {
var options = {
target: '#c_main',
success: setFocus
};
$('#calculator').live('submit', function() {
$(this).ajaxSubmit(options);
return false;
});
$(this).focusin(function(event) {
var shiftDown = false;
$('input, select').each(function (i) {
$(this).data('initial', $(this).val());
});
$('input, select').keyup(function(event) {
if (event.keyCode==16) {
shiftDown = false;
$('#shiftCatch').val(shiftDown);
}
});
$('input, select').keydown(function(event) {
if (event.keyCode==16) {
shiftDown = true;
$('#shiftCatch').val(shiftDown);
}
if (event.keyCode==13) {
$('#captured').val(event.target.id);
} else if (event.keyCode==9 && shiftDown==false) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var nextEl = fields.eq(index+1).attr('id');
var firstEl = fields.eq(0).attr('id');
var focusEl = '#'+firstEl;
if (index>-1 && (index+1)<fields.length) {
$('#captured').val(nextEl);
} else if(index+1>=fields.length) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(firstEl);
} else {
event.preventDefault();
$(focusEl).focus();
}
}
return false;
});
} else if (event.keyCode==9 && shiftDown==true) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var prevEl = fields.eq(index-1).attr('id');
var lastEl = fields.eq(fields.length-1).attr('id');
var focusEl = '#'+lastEl;
if (index<fields.length && (index-1)>-1) {
$('#captured').val(prevEl);
} else if (index==0) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(lastEl);
} else {
event.preventDefault();
$(focusEl).select();
}
}
return false;
});
}
});
});
});
function setFocus() {
with (document.calculator)
var recap = document.getElementById(recaptured.value);
if (recap!=null) {
setTimeout(function() {
if (recap.getAttribute('type')=='text') {
recap.select();
} else {
recap.focus();
}
}, 100 );
}
}
Edit #1: I made a few minor changes to the code, which has brought me a little closer to my intended functionality of the script. However, I only made one change to the code pertaining to the focus: I tried to to disable the tab keydown when pressed on the last element (and also the shift+tab keydown on the first element) in an attempt to force the focus on the element I want without skipping over it like it has been doing. This is the code I added:
$(this).one('keydown', function (event) {
return !(event.keyCode==9 && shiftDown==true);
});
This kind of works. After the page loads, If the user presses tab on the last element without making a change to its value, the focus will be set to the second element. However, the second time the user presses tab on the last element without making a change to its value, and every subsequent time thereafter, the focus will be set to the first element, just as I would like it to.
Edit #2: I replaced the code in Edit #1, with code utilizing event.preventDefault(), which works better. While if a user does a shift+tab keydown when in the first element, the focus moves to the last element as it should. However, if the user continues to hold down the shift key and presses tab again, focus will be set back to the first element. And if the user continues to hold the shift key down still yet and hits tab, the focus will move back to the last element. The focus will shift back and forth between the first and last element until the user lifts the shift key. This problem does not occur when only pressing tab. Here is the new code snippet:
event.preventDefault();
$(focusEl).focus();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您有很多代码我没有得到完整的概述,所以我不知道我是否错过了您想要集成的一些功能,但是对于通过表单元素进行制表/移动制表,这应该可以完成工作:
elements
将是包含所有输入字段的 jQuery 对象,在我的示例中,它是 div#container
内的所有输入字段这是一个演示: http://jsfiddle.net/rA3L9/
You have a lot of code I didn't get full overview over, so I don't know if I missed some functionality you wanted integrated, but for the tabbing/shift-tabbing through form elements, this should do the work:
elements
will be the jQuery object containing all the input fields, in my example it's all the input fields inside the div#container
Here's a demo: http://jsfiddle.net/rA3L9/
这是解决方案,如果没有 Simen 的帮助,我就无法实现该解决方案。再次感谢,西门。
我将文件放在实时链接中可供下载:http://www.presspound。 org/calculator/ajax/sample.php
Here is the solution, which I couldn't have reached it without Simen's help. Thanks again, Simen.
I put my files available to download in my live link: http://www.presspound.org/calculator/ajax/sample.php