使用jquery将焦点更改为下拉元素

时间:2022-08-27 12:11:54

I have the following code. When I press the down/up key, i can successfully select the different value but the focus is still on the main input box. I want to move focus to the selected element. That is if i press down key and if selected element is John Doe, then the focus should also be on John doe element and not on the input box.

我有以下代码。当我按向下/向上键时,我可以成功选择不同的值,但焦点仍在主输入框上。我想将焦点移动到所选元素。也就是说,如果我按下键并且如果选择的元素是John Doe,那么焦点也应该是John doe元素而不是输入框。

I set the following 2 things in the code but they are not working

我在代码中设置了以下两个东西,但它们不起作用

$selected.focus();

and

$current.focus();

What am I doing wrong ?

我究竟做错了什么 ?

3 个解决方案

#1


You can't just focus() a <li> element. From the docs:

你不能只关注()一个

  • 元素。来自文档:

  • The focus event is sent to an element when it gains focus. This event is implicitly applicable to a limited set of elements, such as form elements (<input>, <select>, etc.) and links (<a href>). In recent browser versions, the event can be extended to include all element types by explicitly setting the element's tabindex property. An element can gain focus via keyboard commands, such as the Tab key, or by mouse clicks on the element.

    焦点事件在获得焦点时发送到元素。此事件隐式适用于有限的元素集,例如表单元素(,

    You can try setting the tabindex property.

    您可以尝试设置tabindex属性。

    #2


    LIVE DEMO

    I have added a counter variable , and if counter > 1 then only key Up, Down, Enter method calls, also on Enter Hit again i am setting counter=0 so you get last selected Li. Instead of calling removeClass('selected') everytime, i am calling it only if my counter >1.

    我添加了一个计数器变量,如果计数器> 1,则只键入Up,Down,Enter方法调用,同时再次按Enter键我设置counter = 0,这样你就可以得到最后一个选择的Li。而不是每次调用removeClass('selected'),我只在我的计数器> 1时调用它。

          $(document).ready(function () {
        var $listItems = $('li.autocomplete-list'),
            $div = $('div.autofill'),
            $input = $('#example');
    
        $div.hide();
        var allLI = $(".autocomplete .autocomplete-list");
        var counter = 0;
        $('input#example').on('keydown', function (e) {
            var key = e.keyCode,
                $selected = $listItems.filter('.selected'),
                $current;
            //console.log("Show");
            $div.show();
    
            counter++;
            if (counter > 1) {
                if (key == 40) { // Down key
                    $selected.focus();
                    if (!$selected.length || $selected.is(':last-child')) {
                        $current = $listItems.eq(0);
                    } else {
                        $current = $selected.next();
                    }
                } else if (key == 38) { // Up key
                    if (!$selected.length || $selected.is(':first-child')) {
                        $current = $listItems.last();
                    } else {
                        $current = $selected.prev();
                    }
                } else if (key == 13) {
                    var value = $selected.text().split('(')[0].trim();
                    $input.val(value);
                    $div.hide();
                    counter = 0;
                }
    
                if ($current) {
                    allLI.removeClass('selected');
                    $current.addClass('selected');
                    $current.focus();
                }
            }
        });
    
    
        $('li.autocomplete-list').on('click', function (e) {
            var value = $(this).text().split('(')[0].trim();
            $input.val(value);
            $div.hide();
        });
    
        $('li.autocomplete-list').hover(
    
        function () {
            $(this).addClass('partial_selected')
        },
    
        function () {
            $(this).removeClass('partial_selected')
        });
    
    });
    

    #3


    You need to explicitly assign tabindex property for the list items if you want to focus on them. see http://jsfiddle.net/tkay/40ctx17s/1/ . But a downside to this is you will not be able to move further down in the list since input is not focused.

    如果要关注列表项,则需要为列表项显式指定tabindex属性。见http://jsfiddle.net/tkay/40ctx17s/1/。但是这样做的一个缺点是,由于输入没有集中,你将无法在列表中进一步向下移动。

    $(document).ready(function () {
        var $listItems = $('li.autocomplete-list'),
            $div = $('div.autofill'),
            $input = $('#example');
    
        $div.hide();
    
        $('input#example').on('keydown', function (e) {
            var key = e.keyCode,
                $selected = $listItems.filter('.selected'),
                $current;
    
            $div.show();
    
            $listItems.removeClass('selected');
    
            if (key == 40) { // Down key
                $selected.focus();
                if (!$selected.length || $selected.is(':last-child')) {
                    $current = $listItems.eq(0);
                } else {
                    $current = $selected.next();
                }
            } else if (key == 38) { // Up key
                if (!$selected.length || $selected.is(':first-child')) {
                    $current = $listItems.last();
                } else {
                    $current = $selected.prev();
                }
            } else if (key == 13) {
                var value = $selected.text().split('(')[0].trim();
                $input.val(value) ;
                $div.hide();
            }
    
            if ($current) {
                $current.addClass('selected');
                $current.focus();
                console.log($current);
            }
        });
    
    
        $('li.autocomplete-list').on('click', function (e) {
            var value = $(this).text().split('(')[0].trim();
            $input.val(value);
            $div.hide();
        });
    
        $('li.autocomplete-list').hover(
            function(){ $(this).addClass('partial_selected') },
            function(){ $(this).removeClass('partial_selected') }
        );
    
    });
    .selected {
        background: #a4a4a4;
    }
    .hover {
        background: #A9D0F5;
    }
    ul {
        padding: 5px 0;
    }
    li {
        padding: 6px 3px;
    }
    .autofill {
        width: 250px;
    }
    .input {
        width: 250px;
        height: 2.2em;
        padding: .3em .5em;
        display: block;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <input type="text" class="input" name="example" id="example" placeholder="example..." autocomplete="off" list="examplelist" />
    
    <div class="autofill">
        <ul class="autocomplete">
            <li class="autocomplete-list" tabindex="-1">John Doe (San Jose, CA)</li>
            <li class="autocomplete-list" tabindex="-1">Jane Doe (San Francisco, CA)</li>
            <li class="autocomplete-list" tabindex="-1">John Jane (San Carlos, CA)</li>
        </ul>
    </div>

    Updated Answer after comments of OP

    OP评论后更新的答案

    $(document).ready(function () {
        var $listItems = $('li.autocomplete-list'),
            $div = $('div.autofill'),
            $input = $('#example');
    
        $div.hide();
    
        $('input#example').on('keydown', function (e) {
            var key = e.keyCode,
                $selected = $listItems.filter('.selected'),
                $current;
    
            $div.show();
    
            $listItems.removeClass('selected');
    
            if (key == 40) { // Down key
                $selected.focus();
                if (!$selected.length || $selected.is(':last-child')) {
                    $current = $listItems.eq(0);
                } else {
                    $current = $selected.next();
                }
            } else if (key == 38) { // Up key
                if (!$selected.length || $selected.is(':first-child')) {
                    $current = $listItems.last();
                } else {
                    $current = $selected.prev();
                }
            } else if (key == 13) {
                if ($selected.length){
                e.preventDefault();
               }
                var value = $selected.text().split('(')[0].trim();
                $input.val(value) ;
                $div.hide();
            }
    
            if ($current) {
                $current.addClass('selected');
               
            }
        });
    
    
        $('li.autocomplete-list').on('click', function (e) {
            var value = $(this).text().split('(')[0].trim();
            $input.val(value);
            $div.hide();
        });
    
        $('li.autocomplete-list').hover(
            function(){ $(this).addClass('partial_selected') },
            function(){ $(this).removeClass('partial_selected') }
        );
    
        $("#frm").submit(function(){
            console.log('submitted');
        });
    });
    .selected {
        background: #a4a4a4;
    }
    .hover {
        background: #A9D0F5;
    }
    ul {
        padding: 5px 0;
    }
    li {
        padding: 6px 3px;
    }
    .autofill {
        width: 250px;
    }
    .input {
        width: 250px;
        height: 2.2em;
        padding: .3em .5em;
        display: block;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <form id="frm">
    <input type="text" class="input" name="example" id="example" placeholder="example..." autocomplete="off" list="examplelist" />
        <input type="submit" value="Submit"/>
    </form>
    <div class="autofill">
        <ul class="autocomplete">
            <li class="autocomplete-list">John Doe (San Jose, CA)</li>
            <li class="autocomplete-list">Jane Doe (San Francisco, CA)</li>
            <li class="autocomplete-list">John Jane (San Carlos, CA)</li>
        </ul>
    </div>

    #1


    You can't just focus() a <li> element. From the docs:

    你不能只关注()一个

  • 元素。来自文档:

  • The focus event is sent to an element when it gains focus. This event is implicitly applicable to a limited set of elements, such as form elements (<input>, <select>, etc.) and links (<a href>). In recent browser versions, the event can be extended to include all element types by explicitly setting the element's tabindex property. An element can gain focus via keyboard commands, such as the Tab key, or by mouse clicks on the element.

    焦点事件在获得焦点时发送到元素。此事件隐式适用于有限的元素集,例如表单元素(,

    You can try setting the tabindex property.

    您可以尝试设置tabindex属性。

    #2


    LIVE DEMO

    I have added a counter variable , and if counter > 1 then only key Up, Down, Enter method calls, also on Enter Hit again i am setting counter=0 so you get last selected Li. Instead of calling removeClass('selected') everytime, i am calling it only if my counter >1.

    我添加了一个计数器变量,如果计数器> 1,则只键入Up,Down,Enter方法调用,同时再次按Enter键我设置counter = 0,这样你就可以得到最后一个选择的Li。而不是每次调用removeClass('selected'),我只在我的计数器> 1时调用它。

          $(document).ready(function () {
        var $listItems = $('li.autocomplete-list'),
            $div = $('div.autofill'),
            $input = $('#example');
    
        $div.hide();
        var allLI = $(".autocomplete .autocomplete-list");
        var counter = 0;
        $('input#example').on('keydown', function (e) {
            var key = e.keyCode,
                $selected = $listItems.filter('.selected'),
                $current;
            //console.log("Show");
            $div.show();
    
            counter++;
            if (counter > 1) {
                if (key == 40) { // Down key
                    $selected.focus();
                    if (!$selected.length || $selected.is(':last-child')) {
                        $current = $listItems.eq(0);
                    } else {
                        $current = $selected.next();
                    }
                } else if (key == 38) { // Up key
                    if (!$selected.length || $selected.is(':first-child')) {
                        $current = $listItems.last();
                    } else {
                        $current = $selected.prev();
                    }
                } else if (key == 13) {
                    var value = $selected.text().split('(')[0].trim();
                    $input.val(value);
                    $div.hide();
                    counter = 0;
                }
    
                if ($current) {
                    allLI.removeClass('selected');
                    $current.addClass('selected');
                    $current.focus();
                }
            }
        });
    
    
        $('li.autocomplete-list').on('click', function (e) {
            var value = $(this).text().split('(')[0].trim();
            $input.val(value);
            $div.hide();
        });
    
        $('li.autocomplete-list').hover(
    
        function () {
            $(this).addClass('partial_selected')
        },
    
        function () {
            $(this).removeClass('partial_selected')
        });
    
    });
    

    #3


    You need to explicitly assign tabindex property for the list items if you want to focus on them. see http://jsfiddle.net/tkay/40ctx17s/1/ . But a downside to this is you will not be able to move further down in the list since input is not focused.

    如果要关注列表项,则需要为列表项显式指定tabindex属性。见http://jsfiddle.net/tkay/40ctx17s/1/。但是这样做的一个缺点是,由于输入没有集中,你将无法在列表中进一步向下移动。

    $(document).ready(function () {
        var $listItems = $('li.autocomplete-list'),
            $div = $('div.autofill'),
            $input = $('#example');
    
        $div.hide();
    
        $('input#example').on('keydown', function (e) {
            var key = e.keyCode,
                $selected = $listItems.filter('.selected'),
                $current;
    
            $div.show();
    
            $listItems.removeClass('selected');
    
            if (key == 40) { // Down key
                $selected.focus();
                if (!$selected.length || $selected.is(':last-child')) {
                    $current = $listItems.eq(0);
                } else {
                    $current = $selected.next();
                }
            } else if (key == 38) { // Up key
                if (!$selected.length || $selected.is(':first-child')) {
                    $current = $listItems.last();
                } else {
                    $current = $selected.prev();
                }
            } else if (key == 13) {
                var value = $selected.text().split('(')[0].trim();
                $input.val(value) ;
                $div.hide();
            }
    
            if ($current) {
                $current.addClass('selected');
                $current.focus();
                console.log($current);
            }
        });
    
    
        $('li.autocomplete-list').on('click', function (e) {
            var value = $(this).text().split('(')[0].trim();
            $input.val(value);
            $div.hide();
        });
    
        $('li.autocomplete-list').hover(
            function(){ $(this).addClass('partial_selected') },
            function(){ $(this).removeClass('partial_selected') }
        );
    
    });
    .selected {
        background: #a4a4a4;
    }
    .hover {
        background: #A9D0F5;
    }
    ul {
        padding: 5px 0;
    }
    li {
        padding: 6px 3px;
    }
    .autofill {
        width: 250px;
    }
    .input {
        width: 250px;
        height: 2.2em;
        padding: .3em .5em;
        display: block;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <input type="text" class="input" name="example" id="example" placeholder="example..." autocomplete="off" list="examplelist" />
    
    <div class="autofill">
        <ul class="autocomplete">
            <li class="autocomplete-list" tabindex="-1">John Doe (San Jose, CA)</li>
            <li class="autocomplete-list" tabindex="-1">Jane Doe (San Francisco, CA)</li>
            <li class="autocomplete-list" tabindex="-1">John Jane (San Carlos, CA)</li>
        </ul>
    </div>

    Updated Answer after comments of OP

    OP评论后更新的答案

    $(document).ready(function () {
        var $listItems = $('li.autocomplete-list'),
            $div = $('div.autofill'),
            $input = $('#example');
    
        $div.hide();
    
        $('input#example').on('keydown', function (e) {
            var key = e.keyCode,
                $selected = $listItems.filter('.selected'),
                $current;
    
            $div.show();
    
            $listItems.removeClass('selected');
    
            if (key == 40) { // Down key
                $selected.focus();
                if (!$selected.length || $selected.is(':last-child')) {
                    $current = $listItems.eq(0);
                } else {
                    $current = $selected.next();
                }
            } else if (key == 38) { // Up key
                if (!$selected.length || $selected.is(':first-child')) {
                    $current = $listItems.last();
                } else {
                    $current = $selected.prev();
                }
            } else if (key == 13) {
                if ($selected.length){
                e.preventDefault();
               }
                var value = $selected.text().split('(')[0].trim();
                $input.val(value) ;
                $div.hide();
            }
    
            if ($current) {
                $current.addClass('selected');
               
            }
        });
    
    
        $('li.autocomplete-list').on('click', function (e) {
            var value = $(this).text().split('(')[0].trim();
            $input.val(value);
            $div.hide();
        });
    
        $('li.autocomplete-list').hover(
            function(){ $(this).addClass('partial_selected') },
            function(){ $(this).removeClass('partial_selected') }
        );
    
        $("#frm").submit(function(){
            console.log('submitted');
        });
    });
    .selected {
        background: #a4a4a4;
    }
    .hover {
        background: #A9D0F5;
    }
    ul {
        padding: 5px 0;
    }
    li {
        padding: 6px 3px;
    }
    .autofill {
        width: 250px;
    }
    .input {
        width: 250px;
        height: 2.2em;
        padding: .3em .5em;
        display: block;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <form id="frm">
    <input type="text" class="input" name="example" id="example" placeholder="example..." autocomplete="off" list="examplelist" />
        <input type="submit" value="Submit"/>
    </form>
    <div class="autofill">
        <ul class="autocomplete">
            <li class="autocomplete-list">John Doe (San Jose, CA)</li>
            <li class="autocomplete-list">Jane Doe (San Francisco, CA)</li>
            <li class="autocomplete-list">John Jane (San Carlos, CA)</li>
        </ul>
    </div>