【问题标题】:ajax live search adding key down up featureajax 实时搜索添加按键向下功能
【发布时间】:2020-07-26 23:07:45
【问题描述】:

我想让实时搜索框像 google 一样,我已经在后端实现 jquery ajax 以获取结果,但是我想在用户按下按键时启用我想在 ajax 返回建议中添加一个类,就像谷歌,当用户按下建议时,hightlight 会上升一个地方,当用户按下 enter 时,它将转到 href。以下是我的 ajax 返回 html 代码:

<ul id="suggestion" style="list-style-type: none;">
<li><a class="suggestion-link" href="http://eled.test/post/sunt-iure-nihil-deleniti-rerum"> Sunt Iure Nihil Deleniti Rerum.</a> 
</li>

<li><a class="suggestion-link" href="http://eled.test/post/porro-et-numquam-nihil-nesciunt-nesciunt"> Porro Et Numquam Nihil Nesciunt Nesciunt.</a> 
</li>

<li><a class="suggestion-link" href="http://eled.test/post/my-new-post-yeah"> My New Post Yeah !!</a> </li>

<li><a class="suggestion-link" href="http://eled.test/post/rerum-voluptatem-fuga-excepturi-provident-et-distinctio"> Rerum Voluptatem Fuga Excepturi Provident Et...</a> 
</li>

</ul>

下面是我的搜索表单

<form method="GET" action="{{route('home.search')}}" class="search-form" id="search-form" >
              <div class="form-group">

                <input type="text" name="keyword" id="search-input" placeholder="What are you looking for?" autocomplete="off">

                <button type="submit" class="submit"><i class="fas fa-search"></i></button>
              </div>


              <ul id="suggestion" style="display: none;list-style-type: none; "></ul>
            </form>

下面是我的ajax

$(document).ready(function() {
  //sidebar search function ajax
   $("#search-input").keyup(function() {
       var keyword = $('#search-input').val();
       var url = "{{route('home.ajax_search')}}";
       if (keyword == "") {
           $("#suggestion").html("");
           $('#suggestion').hide();
       }else {
           $.ajax({
               type: "GET",
               url: url ,
               data: {
                   keyword: keyword
               },
               success: function(data) {
                   $("#suggestion").html(data).show();
                   //console.log(data);
                       $('#search-input').on("keydown", function (e) {

                          var listItems = $('.suggestion-link');

                          switch(e.which) {

                              case 38:
                              console.log('up');
                              break;

                              case 40:
                              listItems.addClass('selected');
                              console.log('down');
                              break;
                              default: return;
                          }        

                      });
               }
           });
           
       }

   });

});

在 ajax 内部,当我尝试上下键时,我可以让控制台日志正常工作。 38 / 40 但我无法将所选类添加到我遵循此Add keydown (keyboard arrow up/down) support for AJAX Live Search PHP 的 li 元素 问题是我无法将活动类应用于返回元素,因此用户不会知道向下/向上键正在工作,谢谢

【问题讨论】:

    标签: javascript jquery ajax search


    【解决方案1】:

    首先,在渲染结果时,为每个 li 元素指定一个 ID。 ID 可以是循环的索引。只需确保 ID 是连续的。然后你可以使用类似的东西:

    let highlighted = 0;
    
    $('#search-input').on('keydown', function(e) {
       
       //check if pressed key is down or up
       // 40 is a code for down arrow, 38 for up
    
       if([38, 40].indexOf(e.which) < 0) 
          return;
    
        //remove highlighted class from all list elements here
    
        $('#suggestion').find('li.highligted').removeClass('highligted');    
    
        //handle down and up keypress here
        
        hightlighted = e.which == 40 ? highlighted + 1 : highligted - 1;        
        
        $('#suggestion-'+highlighted).addClass('highligted');
    
    });
    

    【讨论】:

    • 嗨,感谢您的努力,首先我添加了所有 li 元素的突出显示类?第二个添加 unquie ID 从 0 开始的 li 元素?像这样
    【解决方案2】:

    您不应该在success 函数中绑定事件,因为对于每个请求,它都会添加一个新的侦听器,而您的旧侦听器仍处于附加状态,这可能会出现问题。

    从您的问题陈述中,我了解到您想使用向上和向下箭头键突出显示结果 URL。这是一个简短的工作示例,可能会对您有所帮助。

    const field = document.getElementById('search');
    
    let focusIndex = -1;
    
    // When field is focussed, you want to enable up and down navigation
    
    field.onfocus = function () {
      this.classList.add('allow-arrow-nav');
    }
    
    field.onblur = function () {
      this.classList.remove('allow-arrow-nav');
    }
    
    // We will use event delegation to detect if "allow-arrow-nav" class is present
    
    document.body.addEventListener('keydown', (e) => {
      if (e.target.classList.contains('allow-arrow-nav')) {
        // Key codes that we need to target are 38 (up) and 40 (down)
        const allLis = document.querySelectorAll('#searchResults li');
        const totalResults = allLis.length;
        if (e.keyCode === 38 && focusIndex > 0) {
          focusIndex--;
        }
        if (e.keyCode === 40 && focusIndex < totalResults - 1) {
          focusIndex++;
        }
        [...allLis].forEach(liEl => liEl.classList.remove('is-focussed'));
        const selectedLi = document.querySelector(`li[focus-index="${focusIndex}"]`);
        if (selectedLi) {
          selectedLi.classList.add('is-focussed');
          const selectedInnerText = selectedLi.textContent;
          e.target.value = selectedInnerText;
          if (e.keyCode === 13) {
            window.open(selectedLi.querySelector('a').getAttribute('href'), '_blank');
          }
        }
      }
    });
    
    // Since we are delegating the events, you can make the list section dynamic and us a separate function to render it. You need to make sure that all relevant attributes, ids and classes are present to make it work.
    #searchWrapper {
      position: relative;
    }
    
    #searchResults {
      list-style: none;
      display: none;
      margin: 0;
      padding: 4px;
      position: absolute;
      border: 1px solid;
      box-shadow: 0 1px 2px 2px #ccc;
      top: 100%;
    }
    
    #searchResults a {
      color: inherit;
      text-decoration: none;
      padding: 8px;
      display: block;
    }
    
    #searchResults a:hover,
    #searchResults li.is-focussed a {
      background-color: #eee;
    }
    
    #search:focus ~ #searchResults {
      display: block;
    }
    <div id="searchWrapper">
      <input type="text" id="search" />
      <ul id="searchResults">
        <li focus-index="0"><a href="https://google.com" target="_blank">Result 1</a></li>
        <li focus-index="1"><a href="https://google.com" target="_blank">Result 2</a></li>
      </ul>
    </div>

    我希望这会有所帮助。

    【讨论】:

    • 嗨,兄弟,谢谢你的提示,所以关于 ajax 返回数据我必须像这样吗?
    • 跟随焦点索引 0 到 1 ,然后 0 到 1 一次又一次?
  • 不!焦点索引是li 元素的索引。通常,您必须运行一个循环来呈现这些 li 项目。使用循环索引来设置值。
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签