循环聚焦到最后元素和副异常的第一个形式元素

时间:2022-12-03 08:40:25

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:

我已经使用malsup的Form Plugin创建了一个表单,其中它提交了输入的更改。我已经设置了我的jQuery脚本来索引下拉菜单和可见输入,并使用该索引来确定tab的keydown是否应该将焦点移动到下一个元素或第一个元素,同样使用shift + tab keydown。但是,不是像我希望的那样将焦点从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;
            });
        }
    });
});

}); 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 ); } }

}); 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:

编辑#1:我对代码做了一些小改动,这让我更接近我的脚本预期功能。但是,我只对有关焦点的代码进行了一次更改:我试图在按下最后一个元素(以及第一个元素上的shift + tab keydown)时禁用选项卡keydown,试图强制关注我想要的元素,而不像它一直在做的那样跳过它。这是我添加的代码:

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

这种作品。页面加载后,如果用户按下最后一个元素上的Tab而不更改其值,则焦点将设置为第二个元素。但是,第二次用户按下最后一个元素上的tab而不更改其值,以及之后的每个后续时间,焦点将被设置为第一个元素,就像我希望的那样。

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:

编辑#2:我替换了编辑#1中的代码,代码使用了event.preventDefault(),效果更好。如果用户在第一个元素中执行shift + tab keydown,则焦点将移动到最后一个元素。但是,如果用户继续按住shift键并再次按Tab键,则焦点将被设置回第一个元素。如果用户继续按住shift键并按下Tab键,焦点将移回最后一个元素。焦点将在第一个和最后一个元素之间来回移动,直到用户抬起shift键。仅按Tab键不会发生此问题。这是新的代码段:

event.preventDefault();
$(focusEl).focus();

2 个解决方案

#1


1  

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:

你有很多代码我没有得到完整的概述,所以我不知道我是否错过了你想要集成的功能,但是对于tabing / shift-tabbing通过表单元素,这应该做的工作:

var elements = $("#container :input:visible");
var n = elements.length;
elements
.keydown(function(event){
    if (event.keyCode == 9) { //if tab
        var currentIndex = elements.index(this);
        var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
        var el = elements.eq(newIndex);
        if (el.attr("type") == "text")
            elements.eq(newIndex).select();
        else
            elements.eq(newIndex).focus();
        event.preventDefault();
    }
});

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/

元素将是包含所有输入字段的jQuery对象,在我的示例中,它是div中的所有输入字段#container这是一个演示:http://jsfiddle.net/rA3L9/

#2


1  

Here is the solution, which I couldn't have reached it without Simen's help. Thanks again, Simen.

这是解决方案,如果没有Simen的帮助,我无法达到这个目标。再次感谢,西门。

$(document).ready(function() {
    var options = {
        target: '#c_main',
        success: setFocus
    };
    $('#calculator').live('submit', function() {
        $(this).ajaxSubmit(options);
        return false;
    });
    $(this).focusin(function(event) {
        $('#calculator :input:visible').each(function (i) {
            $(this).data('initial', $(this).val());
        });
        return $(event.target).each(function() {
            $('#c_main :input:visible').live(($.browser.opera ? 'keypress' : 'keydown'), function(event){
                var elements = $("#calculator :input:visible");
                var n = elements.length;
                var currentIndex = elements.index(this);
                if (event.keyCode == 13) { //if enter
                    var focusElement = elements.eq(currentIndex).attr('id');
                    $('#captured').val(focusElement);
                } else if (event.keyCode == 9) { //if tab
                    var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
                    var el = elements.eq(newIndex);
                    var focusElement = el.attr('id');
                    if ($(this).val() != $(this).data('initial')) {
                        $('#captured').val(focusElement);
                    } else if ((currentIndex==0 && event.shiftKey) || (currentIndex==n-1 && !event.shiftKey)) { 
                        event.preventDefault();
                        if (el.attr('type')=='text') {
                            $.browser.msie ? "" : $(window).scrollTop(5000);
                            el.select().delay(800);
                        } else {
                            $.browser.msie ? "" : $(window).scrollTop(-5000);
                            el.focus().delay(800);
                        }
                    } else if (el.is('select')) {
                        event.preventDefault();
                        if (el.attr('type')=='text') {
                            el.select();
                        } else {
                            el.focus();
                        }
                    }
                }
            });
        });
    });
});

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();
            }
        }, 1     );
    }
}

I put my files available to download in my live link: http://www.presspound.org/calculator/ajax/sample.php

我把我的文件可以在我的实时链接中下载:http://www.presspound.org/calculator/ajax/sample.php

#1


1  

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:

你有很多代码我没有得到完整的概述,所以我不知道我是否错过了你想要集成的功能,但是对于tabing / shift-tabbing通过表单元素,这应该做的工作:

var elements = $("#container :input:visible");
var n = elements.length;
elements
.keydown(function(event){
    if (event.keyCode == 9) { //if tab
        var currentIndex = elements.index(this);
        var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
        var el = elements.eq(newIndex);
        if (el.attr("type") == "text")
            elements.eq(newIndex).select();
        else
            elements.eq(newIndex).focus();
        event.preventDefault();
    }
});

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/

元素将是包含所有输入字段的jQuery对象,在我的示例中,它是div中的所有输入字段#container这是一个演示:http://jsfiddle.net/rA3L9/

#2


1  

Here is the solution, which I couldn't have reached it without Simen's help. Thanks again, Simen.

这是解决方案,如果没有Simen的帮助,我无法达到这个目标。再次感谢,西门。

$(document).ready(function() {
    var options = {
        target: '#c_main',
        success: setFocus
    };
    $('#calculator').live('submit', function() {
        $(this).ajaxSubmit(options);
        return false;
    });
    $(this).focusin(function(event) {
        $('#calculator :input:visible').each(function (i) {
            $(this).data('initial', $(this).val());
        });
        return $(event.target).each(function() {
            $('#c_main :input:visible').live(($.browser.opera ? 'keypress' : 'keydown'), function(event){
                var elements = $("#calculator :input:visible");
                var n = elements.length;
                var currentIndex = elements.index(this);
                if (event.keyCode == 13) { //if enter
                    var focusElement = elements.eq(currentIndex).attr('id');
                    $('#captured').val(focusElement);
                } else if (event.keyCode == 9) { //if tab
                    var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
                    var el = elements.eq(newIndex);
                    var focusElement = el.attr('id');
                    if ($(this).val() != $(this).data('initial')) {
                        $('#captured').val(focusElement);
                    } else if ((currentIndex==0 && event.shiftKey) || (currentIndex==n-1 && !event.shiftKey)) { 
                        event.preventDefault();
                        if (el.attr('type')=='text') {
                            $.browser.msie ? "" : $(window).scrollTop(5000);
                            el.select().delay(800);
                        } else {
                            $.browser.msie ? "" : $(window).scrollTop(-5000);
                            el.focus().delay(800);
                        }
                    } else if (el.is('select')) {
                        event.preventDefault();
                        if (el.attr('type')=='text') {
                            el.select();
                        } else {
                            el.focus();
                        }
                    }
                }
            });
        });
    });
});

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();
            }
        }, 1     );
    }
}

I put my files available to download in my live link: http://www.presspound.org/calculator/ajax/sample.php

我把我的文件可以在我的实时链接中下载:http://www.presspound.org/calculator/ajax/sample.php