为什么我的ajax元素立即失去了焦点

Why is my ajax element immediately losing focus?

本文关键字:失去 焦点 我的 ajax 元素 为什么      更新时间:2023-09-26

我正在尝试在Wordpress的标题字段中添加一个自动完成选项-我的自定义文档类型之一的标题通常(但并不总是)有一个标准名称。

我已经钩到Wordpress添加一个divsuggestions下面的title的id,并添加一个javascript onKeyUp事件的标题告诉它使一个ajax请求到一个页面,建议基于什么类型到目前为止的名字。一切正常。

目前,然而,我只能通过鼠标点击来选择建议(然后使用val来更新#title的值)。我还希望用户能够使用箭头键来选择建议,就像谷歌一样。

我正在努力通过给每个建议焦点来构建这个(每行是一个li元素和一个动态生成的tabindex)

这工作了一瞬间-预期的元素得到焦点-但随后它立即失去它,回到body。为什么会发生这种情况?

gething .php代码:

<?php
$sofar = stripslashes($_GET['sofar']); // This is important as otherwise the url gets confused and won't work on anything with an apostrophe in it.
$common_file_names = array(
    "Here's suggestion 1",
    "This is suggestion 2",
    "Suggestion 3");
if(strlen($_GET['sofar'])>1) { //Ignores single letters
    echo '<ul id="autocomplete">';
    $tabindex=0;
    foreach ($common_file_names as $suggestion) {
        if(false !== stripos($suggestion, $sofar)) : ?>
            <li 
            tabindex="<?=$tabindex?>" 
            onClick="acceptSuggestion('<?=addslashes($suggestion)?>')"
            onBlur="console.log('Lost focus!'); console.log(document.activeElement);";
            ><?=$suggestion?></li>
        <?php $tabindex++; endif;
    }
    echo '</ul>';
}
?>
JS代码:
$.ajaxSetup({ cache: false });
window.onload = function () {
    $( "<div id='suggestions'></div>" ).insertAfter( "#title" );
    $(document).on('keydown', '#title', function (){
          var hint_slash = this.value;
          showHint(hint_slash);
          checkKey(event);
    });

    $(document).on('focus', '#acf-field-extranet_client_area', function (){
         clearSuggestions();
    });
    $(document).on('focus', '#acf-field-extranet_document_type', function (){
         clearSuggestions();
    });
    $(document).on('focus', '#acf-date_picker', function (){
         clearSuggestions();
    });
    $(document).on('focus', '#acf-file-value', function (){
         clearSuggestions();
    });

    console.log("Scripts loaded successfully");
}
function showHint(str) { //If the user has typed 2 or more characters, this function looks for possible matches among common document names to speed up data entry.
    var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("suggestions").innerHTML = xmlhttp.responseText;
            }
        }
        xmlhttp.open("GET", "/gethint.php?sofar=" + str, true);
        xmlhttp.send();
}

function acceptSuggestion(str) {
    $('#title').val(str); //Puts the clicked suggestion into the title box.
    clearSuggestions();
}
function clearSuggestions() {
    showHint(""); //Clears suggestions.
}
function checkKey(event) {
    console.log('Key press: ' + event.keyCode);
    if(40 == event.keyCode) {
        event.preventDefault(); // Stops scrolling.
        var autocomplete =  $("#autocomplete");
        $(autocomplete.children('li:nth-child(' + 2 + ')')).focus() ;
        console.log(document.activeElement);
        }
    }

这只是目前的测试代码,因此总是将焦点设置为第三个子元素。

我不会把注意力集中在建议上。在这种情况下,您必须为每个建议添加键检查代码,因为输入将失去焦点。相反,为"聚焦"建议创建一个CSS类,删除上/下键上的类,并将其添加到上/下一个建议中……

 $input.keyup(function(e) {
    if(e.which == 38) {
        // up key
        var active = $('.suggestions li.active');
        if(active.length) {
            active.removeClass('active');
            active.prev().addClass('active');
        } else {
            $('.suggestions li:last').addClass('active');
        }
    } else if(e.which == 40) {
        // down key
        var active = $('.suggestions li.active');
        if(active.length) {
            active.removeClass('active');
            active.next().addClass('active');
        } else {
            $('.suggestions li:first').addClass('active');
        }
    }
});

基于@evilunix的回答,我意识到每次击键都重置#suggestionsdiv,这意味着它永远无法保持焦点(或保持附加的类等)。

所以,我写了一个新的函数叫做checkKey:
function checkKey(e) {  
    if(e.which == 38) {
        // up key
        e.preventDefault(); //Stops scrolling and cursor movement.
        var active = $('#suggestions li.active');
        if(active.length) {
            active.removeClass('active');
            active.prev().addClass('active');
        } else {
            $('#suggestions li:last').addClass('active');
        }
    } else if(e.which == 40) {
        // down key
        e.preventDefault(); //Stops scrolling and cursor movement.
        var active = $('#suggestions li.active');
        if(active.length) {
            active.removeClass('active');
            active.next().addClass('active');
        } else {
            $('#suggestions li:first').addClass('active');
        }
    } else if(e.which == 13) {
        //Return key
        e.preventDefault(); //Stops form submission.
        acceptSuggestion(document.getElementsByClassName('active')[0].innerHTML);
    } else {
        console.log(e.which);
        showHint($('#title').val());    
    }
}

并将#title的onKeydown事件更改为:

$(document).on('keydown', '#title', function (){
        checkKey(event);
});

现在#suggestions只有在击键不是向上箭头、向下箭头或返回时才刷新,并且在返回时运行acceptSuggestion,无论li具有active类。