jquery 按向下箭头键跳到下一个tabindex字段

wwodge7n  于 9个月前  发布在  jQuery
关注(0)|答案(4)|浏览(155)

我有一个web表单,并希望用户能够进入下一个tabindex字段时,向下箭头被按下(行为像标签键)。下面的代码工程时,回车键被按下,但如果我改变键代码为40这段代码将无法为向下箭头键工作。
任何帮助非常感谢。

<div>
    <input name="line[]" class=""  type="text" tabindex="1"/>
</div>
<div>
    <input name="line[]" class=""  type="text" tabindex="2"/>
</div>
<div>
    <input name="line[]" class=""  type="text" tabindex="3"/>
</div>

//tab to next tabindex on enter key
<script>
    var id;
    $(document).ready(function(eOuter) {
        $('input').bind('keypress', function(eInner) {
            if (eInner.keyCode == 13){ //enter key
                var tabindex = $(this).attr('tabindex');
                tabindex++; //increment tabindex
                $('[tabindex=' + tabindex + ']').focus();

                $('#Msg').text($(this).attr('id') + " tabindex: " + tabindex + " next element: " + $('*').attr('tabindex').id);
            }
        });
    });
</script>

字符串

fxnxkyjh

fxnxkyjh1#

箭头键在keypress事件上不一致,您希望使用keydown

$('input').on('keydown', function(eInner) {

    if (eInner.which === 40) { //arrow down

字符串
FIDDLE
你的消息也有一些问题,元素没有ID,jQuery的attr返回一个没有id属性的原语等。

xxe27gdn

xxe27gdn2#

**100%**适用于up arrowdown arrow

$(document).ready(function(eOuter) {
     $('input').on('keydown', function(eInner) {
         var keyValue = eInner.which; //enter key
         if (keyValue == 40 || keyValue == 38){ 
             var tabindex = $(this).attr('tabindex');
             if(keyValue == 40){ //down arrow 40
                 tabindex++;
             }else{ //up arrow 38
                 tabindex--;
             }
             $('[tabindex=' + tabindex + ']').focus();
         }
     });
});

字符串

ijxebb2r

ijxebb2r3#

对于任何想知道这在React/Typescript代码中如何工作的人,这里有一个代码片段对我有用(允许使用ArrowDown和ArrowUp键来实现tab通过ul列表的效果):

<ul>
            {props.suggestions.map((o, i, a) => (
                <li
                    key={o.id}
                    tabIndex={props.tabIndex}
                    onClick={(e) => (props.onSelect ? props.onSelect(o) : undefined)}
                    onBlur={props.onBlur}
                    onKeyDown={(e) => {
                        if (e.key === 'Enter') {
                            if (props.onSelect) props.onSelect(o);
                        }

                        if (e.key === 'ArrowDown') {
                            e.currentTarget.nextSibling && e.currentTarget.nextSibling.focus();
                        }
                        if (e.key === 'ArrowUp') {
                            e.currentTarget.previousSibling && e.currentTarget.previousSibling.focus();
                        }
                    }}
                />
                
            ))}
        </ul>

字符串
键是e.currentTarget.nextSibling.focus()e.currentTarget.previousSibling.focus()

oknwwptz

oknwwptz4#

这比我想象的要难,但如果这对你很重要,就像对我们一样,这是你需要做的...

  • 遍历DOM以创建和维护您自己的可接收焦点的元素的有序列表。
  • 创建一个变量active,它将跟踪当前聚焦的输入。
  • 侦听焦点事件,以便在用户通过Tab键或单击聚焦输入时更新active的值。
  • 监听箭头键,并使用active确定列表中的下一个或上一个元素,并对其调用focus()
  • 模糊。如果用户在输入外单击,则制表符重置为零。如果您希望将其用于箭头键,则必须添加它。(下面的代码不管理此功能)

下面的代码在react中完成了所有这些(除了最后一点)。它应该可以很容易地适应任何其他设置。它在调用后500 ms建立一次列表。这对我们来说已经足够了,但是如果你要从DOM中添加和删除输入,你需要自己管理。

import { useEffect, useRef, useState } from "react";
import { IHasHistory, withHistory } from "./traceableEvents";

function addArrowNavigation() {

    function onFocus(e: FocusEvent & IHasHistory) {
        if (!e.history.includes("focusManager.OnFocus")) {
            const activeIndex = inputsRef.current.findIndex((anInput) => anInput === e.target);
            setActive(activeIndex);
            console.log(activeIndex + " active");
            e.history.push("focusManager.OnFocus");
        }
    }

    // stores list of all elements in the page that
    // can receive focus, in order of their appearance.
    const [inputs, setInputs] = useState([]);
    const inputsRef = useRef(inputs)
    useEffect(() => { inputsRef.current = inputs })

    // stores the currently focussed input
    const [active, setActive] = useState<number | undefined>(undefined);
    const activeRef = useRef(active)
    useEffect(() => { activeRef.current = active })

    function registerTabbable(doc: Document) {
        const inputs = [];
        function traverse(el: HTMLElement) {
            if (el.tabIndex >= 0) {
                inputs.push(el);
            }
            if (el.childNodes) {
                for (const node of el.childNodes)
                    if (node instanceof HTMLElement)
                        traverse(node);
            }
        }
        for (const node of doc.childNodes)
            if (node instanceof HTMLElement)
                traverse(node);

        console.log(inputs);
        setInputs(inputs);
    }

    useEffect(() => {
        document.addEventListener("keydown", keyPress);
        document.addEventListener("focusin", (e) =>
            onFocus(withHistory(e))
        );

        setTimeout(() => {
            registerTabbable(document);
        }, 500);

        // Don't forget to clean up
        return function cleanup() {
            document.removeEventListener("keydown", keyPress);
        };
    }, []);

    const keyPress = (e: KeyboardEvent) => {
        console.log(e.keyCode);
        if ([38, 40].includes(e.keyCode)) e.preventDefault();
        switch (e.keyCode) {
            // DOWN ARROW
            case 40: {
                const goTo = activeRef.current === undefined ? 0 : (activeRef.current + 1) % inputsRef.current.length
                inputsRef.current[goTo].focus();
                break;
            }
            // UP ARROW
            case 38: {
                const goTo = activeRef.current === undefined ? 0 : (activeRef.current - 1) % inputsRef.current.length
                inputsRef.current[goTo].focus();
                break;
            }
        }
    }
}

字符串
上面提到的traceableEvents组件如下.

export interface IHasHistory {
    history: string[];
}

export function withHistory<TargetShape>(target: any): TargetShape & IHasHistory {
    if (!target.history) {
        (target as IHasHistory).history = [];
    }
    return target;
}

相关问题