JQuery自动完成功能不适用于第一个按键事件(源是一个数组)

时间:2018-01-25 13:44:08

标签: javascript jquery ajax jquery-ui autocomplete

我正在创建像Google这样的搜索结果自动填充功能。

自动完成的结果(或来源)将是一个动态数组(该数组是使用从URL调用中的$.ajax属性访问的对象创建的)并且元素在每个keypress事件。

我的意思很简单:

  1. 我们有一个变量autocompleteResults
  2. $.ajax成功回调函数中,我们将此变量分配给空数组:autocompleteResults = []
  3. 在此之后,我们正在执行$.each()功能:

    $.each(d.query.pages, function(i) {
      autocompleteResults.push(d.query.pages[i].title);
    });  
    
    // d.query.pages - JSON object from the success callback (success: function(d) {...}
    
  4. 我们在成功回调结束时致电callback(autocompleteResults)

  5. 调用此函数并正确返回数组:

    getAutocompleteResults(function() {
      console.log(autocompleteResults);
    });
    
  6. 然后在相同的范围内:

    $("#search").autocomplete({source: autocompleteResults},...);
    

    它仅适用于我第二次输入内容。

  7. 使用图片快速概述:

    1. 首次查看重新加载后的页面: enter image description here
    2. 让我们在输入字段中输入内容(例如“a”): enter image description here
    3. 正如您在上一张图片中看到的那样,我们没有自动完成结果(“一个”结果只是JS创建的一个表,与此问题无关)。让我们尝试使用键盘上的退格键删除“a”字符: enter image description here
    4. 我们得到的结果与第一张图片相同。但等等,有些事情发生了变化。让我们尝试输入与第二张图像相同的密钥,看看我们得到了什么: enter image description here
    5. 奇迹!在上一张图片中,一切都是它应该是什么样子。只有在第二次尝试将某些内容输入字段后才能实现此结果的问题。它应该在第一次尝试时起作用。
    6. 关于这个问题的所有研究成果:

      1. 如果未将自动填充放在keypress事件函数中,则自动填充功能完美无缺。但是,在这种情况下,我们得到结果一次,然后它停止响应未来类型(输入“a” - 5个结果,输入“aa” - 结果与“a”相同,并且它没有响应。< / p>

        我认为我应该使用所述here$( ".selector" ).autocomplete( "search", "" );来重新更改来源,但我不确定它是否可以解决此问题。

      2. 我的代码以某种方式堆叠了AJAX请求,并且多次重复相同的请求。我怎么能解决这个问题?: enter image description here

      3. 这些主题没有帮助: jQuery UI autocomplete with JSONjQuery autocomplete with callback ajax jsonJquery Autocomplete Search with Ajax Request as sourcedatahttps://forum.jquery.com/topic/autocomplete-with-ajax-and-json-not-working

      4. 要查看完整的项目代码,请访问: https://codepen.io/Kestis500/pen/PErONL?editors=0010

        或者使用一小段代码(这样您就可以看到问题发生的最重要部分):

        $(function() {
          var autocompleteResults;
          var changeText2 = function(e) {
            var request = $("input").val() + String.fromCharCode(e.which);
            $("#instant-search").text(request);
        
            var getAutocompleteResults = function(callback) {
              $.ajax({
                url: "https://en.wikipedia.org/w/api.php?action=query&format=json&gsrlimit=5&generator=search&origin=*&gsrsearch=" + $('#instant-search').text(),
                success: function(d) {
        
                  autocompleteResults = [];
                  $.each(d.query.pages, function(i) {
                    autocompleteResults.push(d.query.pages[i].title);
                  });
        
                  callback(autocompleteResults);
                },
                datatype: "json",
                cache: false
              });
            };
        
            getAutocompleteResults(function() {
              console.log(autocompleteResults);
            });
        
        
        
        
            $("#search").autocomplete({
              source: autocompleteResults,
              response: function() {
                if (
                  $("#instant-search")
                  .text()
                ) {
                  $("table").css("display", "table");
                }
              },
              close: function() {
                if (!$(".ui-autocomplete").is(":visible")) {
                  $(".ui-autocomplete").show();
                }
              },
              appendTo: ".input",
              focus: function(e) {
                e.preventDefault();
              },
              delay: 0
            });
        
        
          };
        
          var changeText1 = function(e) {
            if (
              /[-a-z0-90áãâäàéêëèíîïìóõôöòúûüùçñ!@#$%^&*()_+|~=`{}\[\]:";'<>?,.\s\/]+/gi.test(
                String.fromCharCode(e.which)
              )
            ) {
              $("input").on("keypress", changeText2);
            }
        
        
        
            // THIS PART HAS NOTHING TO DO WITH THIS PROBLEM AND DELETING THIS WOULD MAKE A TABLE CREATED BY THE HTML TO NOT FUNCTION
            var getInputSelection = function(input) {
              var start = 0,
                end = 0;
              input.focus();
              if (
                typeof input.selectionStart == "number" &&
                typeof input.selectionEnd == "number"
              ) {
                start = input.selectionStart;
                end = input.selectionEnd;
              } else if (document.selection && document.selection.createRange) {
                var range = document.selection.createRange();
                if (range) {
                  var inputRange = input.createTextRange();
                  var workingRange = inputRange.duplicate();
                  var bookmark = range.getBookmark();
                  inputRange.moveToBookmark(bookmark);
                  workingRange.setEndPoint("EndToEnd", inputRange);
                  end = workingRange.text.length;
                  workingRange.setEndPoint("EndToStart", inputRange);
                  start = workingRange.text.length;
                }
              }
              return {
                start: start,
                end: end,
                length: end - start
              };
            };
        
            switch (e.key) {
              case "Backspace":
              case "Delete":
                e = e || window.event;
                var keyCode = e.keyCode;
                var deleteKey = keyCode == 46;
                var sel, deletedText, val;
                val = this.value;
                sel = getInputSelection(this);
                if (sel.length) {
                  // 0 kai paprastai trini po viena o 1 ar daugiau kai select su pele trini
                  $("#instant-search").text(
                    val.substr(0, sel.start) + val.substr(sel.end)
                  );
                } else {
                  $("#instant-search").text(
                    val.substr(0, deleteKey ? sel.start : sel.start - 1) +
                    val.substr(deleteKey ? sel.end + 1 : sel.end)
                  );
                }
                break;
              case "Enter":
                if (
                  $("#instant-search")
                  .text()
                  .trim()
                ) {
                  console.log("Redirecting...");
                }
                break;
            }
        
            if (!$("#instant-search")
              .text()
              .trim()
            ) {
              $("table, .ui-autocomplete").hide();
            }
          };
        
          $("input").on("keydown", changeText1);
        
        
        
        
        
        
        
        
        
        
          $("input").on("input", function(e) {
            $("#instant-search").text($("#search").val());
            if (
              $("#instant-search")
              .text()
              .trim()
            ) {
              $('table').css('display', 'table');
            } else {
              $("table").hide();
            }
          });
        });
        html,
        body {
          height: 100%;
          width: 100%;
        }
        
        body {
          margin: 0;
          padding: 0;
          font-family: sans-serif;
          background-color: #000428;
          /* fallback for old browsers */
          background-image: -webkit-linear-gradient(to right, #004e92, #000428);
          /* Chrome 10-25, Safari 5.1-6 */
          background-image: linear-gradient(to right, #004e92, #000428);
          /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
        }
        
        .v-container {
          display: table;
          height: 100%;
          width: 100%;
        }
        
        .v-content {
          display: table-cell;
          vertical-align: middle;
        }
        
        .text-center {
          text-align: center;
        }
        
        h1 {
          color: #fff;
        }
        
        .input {
          overflow: hidden;
          white-space: nowrap;
        }
        
        .input input#search {
          width: calc(100% - 30px);
          height: 50px;
          border: none;
          font-size: 10pt;
          float: left;
          color: #4f5b66;
          padding: 0 15px;
          outline: none;
        }
        
        .input button.icon {
          border: none;
          height: 50px;
          width: 50px;
          color: #4f5b66;
          background-color: #fff;
          border-left: 1px solid #ddd;
          margin-left: -50px;
          outline: none;
          cursor: pointer;
          display: none;
          -webkit-transition: background-color .5s;
          transition: background-color .5s;
        }
        
        .input button.icon:hover {
          background-color: #eee;
        }
        
        .ui-autocomplete {
          list-style: none;
          background-color: #fff;
          -webkit-user-select: none;
          user-select: none;
          padding: 0;
          margin: 0;
          width: 100% !important;
          top: auto !important;
          display: table;
          table-layout: fixed;
        }
        
        .ui-helper-hidden-accessible {
          display: none;
        }
        
        .autocomplete-first-field {
          width: 15%;
          display: inline-block;
        }
        
        .autocomplete-second-field {
          width: 85%;
          display: inline-block;
          text-align: left;
          vertical-align: middle;
        }
        
        .three-dots {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        
        table {
          width: 100%;
          border-spacing: 0;
          border-collapse: collapse;
          display: none;
          table-layout: fixed;
        }
        
        table tr {
          background-color: #fff;
          -webkit-user-select: none;
          user-select: none;
        }
        
        tr:first-child {
          background-color: #ffc800;
          color: #fff;
        }
        
        table td,
        .ui-menu-item-wrapper {
          padding: 10px 0;
        }
        
        td:nth-child(2) {
          width: 85%;
          text-align: left;
        }
        
        .ui-menu-item,
        table {
          cursor: pointer;
        }
        
        :focus {
          outline: 0;
        }
        
        a {
          text-decoration: none;
          color: #fff;
          position: relative;
        }
        
        #random-article {
          margin-bottom: 5px;
        }
        
        .search-results {
          background: #fff;
          margin-top: 50px;
          border-left: 0 solid;
          cursor: pointer;
          -webkit-transition: border-left .5s;
          transition: border-left .5s;
        }
        
        .search-results h4,
        .search-results p {
          margin: 0;
          padding: 10px;
        }
        
        .search-results:not(:first-child) {
          margin-top: 25px;
        }
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
        <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
        <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
        <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
        <!--[if gt IE 8]><!-->
        <html class="no-js">
        <!--<![endif]-->
        <div class="v-container">
          <div class="v-content text-center">
            <div id="random-article"><a href="https://en.wikipedia.org/wiki/Special:Random">Click here for a random WikiSearch article! :)</a></div>
            <div class="input">
              <input type="text" id="search" placeholder="Search...">
              <button class="icon"><i class="fa fa-search"></i></button>
        
              <table>
                <tr>
                  <td class="fa fa-search">
                    <td id="instant-search" class="three-dots"></td>
                </tr>
              </table>
            </div>
          </div>
        </div>

        如果您有任何想法如何解决此问题,我们将非常感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

您已将source: autocompleteResults,保留在autocompleteResults动态更改的位置,您应该做这样的事情

source: function (request, response) {
    getAutocompleteResults(function(data){
      response(data);
    });
  },

工作代码https://codepen.io/anon/pen/OzeQvw?editors=0010