首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由于变量范围,jQuery response()函数不返回任何结果

由于变量范围,jQuery response()函数不返回任何结果
EN

Stack Overflow用户
提问于 2018-01-27 14:03:01
回答 1查看 221关注 0票数 0

我遇到的问题是,由于变量范围,我无法从jQuery UI自动完成表单中获得任何结果。让我来给你展示。

代码语言:javascript
复制
// TAKE A CLOSE LOOK AT THIS METHOD
select: function(e, ui) {

$('#instant-search').text(ui.item.label);
$("#search").autocomplete("option", "source",
  function(request, response) {
    getAutocompleteResults(function(d) {
      // DOESN'T WORK response(d);
    });
    // WORKS BUT IT SHOULD BE A DYNAMIC ARRAY FROM THE "D" OBJECT
    // response(["anarchism", "anarchist black cross", "black rose (symbolism)", "communist symbolism", "political symbolism"]);
  });

$("#search").autocomplete("search", ui.item.label);

为了返回结果,我必须在response([...]);函数之外使用一个函数getAutocompleteResults(function(d) { ... });

但是,源应该是动态的,而不是静态数组。换言之:

函数response(d);应该返回一个对象,该对象包含一些属性(标题、值、提取)。我必须使用response(d);来访问它们,但是这个函数在getAutocompleteResults(function(d) { ... });函数中不能工作。我怎样才能做到这一点?

有一个小的代码片段,但是,主要的问题是select方法。您可以在整个代码块的中间找到这个。我评论了一下。

代码语言:javascript
复制
$(function() {
  $("html").removeClass("no-js");
  var autocompleteResults = [{
    title: [],
    extract: [],
    pageId: []
  }];

  var capitalizeFirstLetter = function(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
  };

  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?format=json&action=query&generator=search&gsrlimit=6&prop=extracts&origin=*&pilimit=max&exintro&explaintext&exsentences=1&gsrsearch=" +
          $("#instant-search").text(),
        beforeSend: function() {
          $(".loading").show();
        },
        success: function(d) {
          $(".loading").hide();
          autocompleteResults[0].title = [];
          autocompleteResults[0].extract = [];
          autocompleteResults[0].pageId = [];

          if (d.hasOwnProperty("query")) {
            if (d.query.hasOwnProperty("pages")) {
              $.each(d.query.pages, function(i) {
                autocompleteResults[0].title.push(d.query.pages[i].title);

                autocompleteResults[0].extract.push(d.query.pages[i].extract);
                autocompleteResults[0].pageId.push(d.query.pages[i].pageid);
              });
            }
          }

          if (!autocompleteResults[0].length) {
            $(".ui-autocomplete").hide();
          }


          autocompleteResults[0].title.sort(function(a, b) {
            var nameA = a.toUpperCase();
            var nameB = b.toUpperCase();
            if (nameA < nameB) {
              return -1;
            }
            if (nameA > nameB) {
              return 1;
            }

            return 0;
          });

          autocompleteResults[0].title = autocompleteResults[0].title.map(
            function(i) {
              return i.toLowerCase();
            }
          );

          callback(autocompleteResults[0]);
        },
        datatype: "json",
        cache: false
      });
    };

    $("#search").autocomplete({
      source: function(request, response) {
        getAutocompleteResults(function(d) {
          var results = [],
            filteredAutocompleteResults = [];

          filteredAutocompleteResults = d.title.filter(function(i) {
            return (
              i !=
              $("#instant-search")
              .text()
              .toLowerCase()
            );
          });

          for (var i = 0; i < d.title.length; i++) {
            results[i] = {
              label: filteredAutocompleteResults[i],
              extract: d.extract[i],
              pageId: d.pageId[i]
            };
          }

          if (results.length == 5) {
            response(results);
          } else {
            response(results.slice(0, 5));
          }
        });
      },
      response: function() {
        if ($("#instant-search").text()) {
          $("table").css("display", "table");
          $(".wikisearch-container").css("margin-top", 100);
        }
      },
      close: function() {
        if (!$(".ui-autocomplete").is(":visible")) {
          $(".ui-autocomplete").show();
        }
      },
      appendTo: ".input",
      focus: function(e) {
        e.preventDefault();
      },
      delay: 0,












      // TAKE A CLOSE LOOK AT THIS METHOD
      select: function(e, ui) {

        $('#instant-search').text(ui.item.label);
        $("#search").autocomplete("option", "source",
          function(request, response) {
            getAutocompleteResults(function(d) {
              // DOESN'T WORK response(d);
            });
            // WORKS BUT IT SHOULD BE A DYNAMIC ARRAY FROM THE "D" OBJECT
            // response(["anarchism", "anarchist black cross", "black rose (symbolism)", "communist symbolism", "political symbolism"]);
          });

        $("#search").autocomplete("search", ui.item.label);










        // EVERYTHING SHOULD BE FINE BELOW THIS LINE

        if ($(".search-results").css("opacity") != 1) {
          $(".search-results h4").text(capitalizeFirstLetter(ui.item.label));
          $(".search-results p").text(ui.item.extract);
          $(".search-results a").prop(
            "href",
            "https://en.wikipedia.org/?curid=" + ui.item.pageId
          );
          $(".search-results").css("opacity", 1);
        } else if (
          $(".search-results h4")
          .text()
          .toLowerCase() != ui.item.label
        ) {
          $(".search-results").css("opacity", 0);
          setTimeout(function() {
            $(".search-results h4").text(capitalizeFirstLetter(ui.item.label));
            $(".search-results p").text(ui.item.extract);
            $(".search-results a").prop(
              "href",
              "https://en.wikipedia.org/?curid=" + ui.item.pageId
            );
            $(".search-results").css("opacity", 1);
          }, 500);
        }
      },
      create: function() {
        $(this).data("ui-autocomplete")._renderItem = function(ul, item) {
          return $("<li>")
            .append(
              '<div class="ui-menu-item-wrapper"><div class="autocomplete-first-field"><i class="fa fa-search" aria-hidden="true"></i></div><div class="autocomplete-second-field three-dots">' +
              item.label +
              "</div></div>"
            )
            .appendTo(ul);
        };
      }
    });
  };


  var changeText1 = function(e) {
    if (
      /[-a-z0-90áãâäàéêëèíîïìóõôöòúûüùçñ!@#$%^&*()_+|~=`{}\[\]:";'<>?,.\s\/]+/gi.test(
        String.fromCharCode(e.which)
      )
    ) {
      $("input").on("keypress", changeText2);
    }


    // DONT TOUCH THIS AREA, IT HAS NOTHING TO DO WITH THE PROBLEM
    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()) {
          console.log("Redirecting...");
        }
        break;
    }

    if (!$("#instant-search").text()) {
      $("table, .ui-autocomplete").hide();
      $(".wikisearch-container").css("margin-top", "");
    }

    if (
      $(".ui-menu-item-wrapper").hasClass("ui-state-active") &&
      (e.key == "ArrowRight" || e.key == "ArrowLeft")
    ) {
      $(".ui-autocomplete").autocomplete(""); // Error metas console ir taip neturėtų būti bet nežinau kaip padaryti kad pasirinkus elementą su <-- ar --> nepadarytų tik vieno rezultato todėl paliekam laikinai ;)
    }
  };

  $("input").on("keydown", changeText1);

  $("input").on("input", function(e) {
    $("#instant-search").text($("#search").val());
  });

});
代码语言:javascript
复制
html,
body {
  height: 100%;
  width: 100%;
}

body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  background-image: url("http://www.part.lt/img/96816a00ec1fb87adc4ca8a04365b2b5719.jpg");
  background-size: cover;
  background-position: 100%;
}

.v-container {
  display: table;
  height: 100%;
  width: 100%;
}

.v-content {
  display: table-cell;
  vertical-align: middle;
}

.text-center {
  text-align: center;
}

.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;
}

.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;
}

a:before {
  content: "";
  position: absolute;
  width: 100%;
  height: 0.0625rem;
  bottom: 0;
  left: 0;
  background-color: #fff;
  visibility: hidden;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transition: all 0.3s ease-in-out 0s;
  transition: all 0.3s ease-in-out 0s;
}

a:hover:before {
  visibility: visible;
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}

.search-results {
  background: #fff;
  margin-top: 50px;
  border-left: 5px solid #0ebeff;
  opacity: 0;
  -webkit-transition: opacity 1s;
  transition: opacity 1s;
}

.search-results h4,
.search-results p {
  margin: 0;
  padding: 10px;
  text-align: left;
}

.search-results a {
  color: #0ebeff;
  display: inline-block;
  margin: 1rem 0;
}

.search-results a:before {
  background-color: #0ebeff;
}

.wikisearch-container {
  width: 65%;
  margin: 0 auto;
}


/* Loading animation */

@keyframes lds-eclipse {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  50% {
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@-webkit-keyframes lds-eclipse {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  50% {
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

.loading {
  position: relative;
  top: 9.5px;
  right: 15px;
  pointer-events: none;
  display: none;
}

.lds-eclipse {
  -webkit-animation: lds-eclipse 1s linear infinite;
  animation: lds-eclipse 1s linear infinite;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  margin-left: auto;
  box-shadow: 0.08rem 0 0 #0ebeff;
}

@media (max-width: 71.875em) {
  .wikisearch-container {
    width: 75%;
  }
}

@media (max-width: 50em) {
  .wikisearch-container {
    width: 85%;
  }
}

@media (max-width: 17.96875em) {
  .wikisearch-container {
    width: 100%;
  }
}
代码语言:javascript
复制
<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>
<html class="no-js">
<div class="v-container">
  <div class="v-content text-center">
    <div class="wikisearch-container">
      <div class="input">
        <input type="text" id="search" placeholder="Search...">
        <div class="loading">
          <div class="lds-eclipse"></div>
        </div>
        <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 class="search-results">
        <h4></h4>
        <p></p>
        <a target="_blank">Click here for more</a>
      </div>
    </div>
  </div>
</div>

编辑1经过一些更改后,结果将显示在ajax调用之前。只有在ajax成功完成之后,我才能使用response() (尝试使用success回调,但没有工作:() )。

完整的项目代码:https://codepen.io/Kestis500/pen/zRONyw?editors=0010

在这里,您可以一步一步地看到它的样子:

  1. 当您刚刚重新加载页面时,它是什么样的:

  1. 让我们试着输入"a":

  1. 我们得到了一些结果。好的,让我们试着点击“无政府主义象征主义”元素:

  1. 结果应该看起来像“无政府主义象征主义”的探索。但是,它返回"a“搜索的结果。如果我们按下"fraktur“元素呢?

  1. 现在它展示了我们之前搜索的“无政府主义象征主义”的结果。但是,它应该返回"fraktur“搜索的元素。

编辑2 --我修复了许多东西,并从代码中删除了一些真正没有意义的东西。但是,ajax调用的情况仍然一样。

https://codepen.io/Kestis500/pen/pazppP?editors=0110

有什么想法吗?

编辑3固定的ajax滞后(现在ajax请求将只在之前的ajax调用之后发送)。

https://codepen.io/Kestis500/pen/JpPLON?editors=0110

EN

回答 1

Stack Overflow用户

发布于 2018-01-27 20:57:30

我必须首先修复Ajax调用中的一些内容。然后我们收集结果并构建一个应该返回给response()的数组。这将填充AutoComplete。

首先,我们将检查HTML。有一些结束标记不见了。

代码语言:javascript
复制
<div class="v-container">
  <div class="v-content text-center">
    <div class="wikisearch-container">
      <div class="input ui-front">
        <input type="text" id="search" placeholder="Search...">
        <div class="loading">
          <div class="lds-eclipse"></div>
        </div>
        <button class="icon">
          <i class="fa fa-search"></i>
        </button>
        <table>
          <tr>
            <td class="fa fa-search"></td>
            <td id="instant-search" class="three-dots"></td>
          </tr>
        </table>
      </div>
      <div class="search-results">
        <h4></h4>
        <p></p>
        <a target="_blank">Click here for more</a>
      </div>
    </div>
  </div>
</div>

您可以看到table,它的单元格现在都有正确的结束标记。

我没有对你的CSS或样式做任何改变。

JavaScript

代码语言:javascript
复制
$(function() {
  var capitalizeFirstLetter = function(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
  };
  $("#search").autocomplete({
    source: function(request, response) {
      var results = [];
      $.ajax({
        url: "https://en.wikipedia.org/w/api.php",
        data: {
          format: "json",
          action: "query",
          generator: "search",
          gsrlimit: 6,
          prop: "extracts|pageimages",
          origin: "*",
          pilimit: "max",
          exintro: false,
          explaintext: false,
          exsentences: 1,
          gsrsearch: request.term
        },
        beforeSend: function() {
          $(".loading").show();
        },
        success: function(d) {
          $(".loading").hide();
          if (d.query.pages) {
            $.each(d.query.pages, function(k, v) {
              console.log(k, v.title, v.extract, v.pageid);
              results.push({
                label: v.title,
                value: "https://en.wikipedia.org/?curid=" + v.pageid,
                title: v.title,
                extract: v.extract,
                pageId: v.pageid
              });
            });
            response(results);
          }
        },
        datatype: "json",
        cache: false
      });
      response(results);
    },
    close: function() {
      if (!$(".ui-autocomplete").is(":visible")) {
        $(".ui-autocomplete").show();
      }
    },
    focus: function(e) {
      e.preventDefault();
      return false;
    },
    delay: 0,
    select: function(e, ui) {
      if ($(".search-results").css("opacity") != 1) {
        $(".search-results h4").text(capitalizeFirstLetter(ui.item.label));
        $(".search-results p").text(ui.item.extract);
        $(".search-results a").prop(
          "href",
          ui.item.value
        );
        $(".search-results").css("opacity", 1);
      } else if (
        $(".search-results h4")
        .text()
        .toLowerCase() != ui.item.label
      ) {
        $(".search-results").css("opacity", 0);
        setTimeout(function() {
          $(".search-results h4").text(capitalizeFirstLetter(ui.item.label));
          $(".search-results p").text(ui.item.extract);
          $(".search-results a").prop(
            "href",
            ui.item.value
          );
          $(".search-results").css("opacity", 1);
        }, 500);
      }
      return false;
    }
  }).autocomplete("instance")._renderItem = function(ul, item) {
    var $item = $("<li>");
    var $wrap = $("<div>").appendTo($item);
    var $field1 = $("<div>", {
      class: "autocomplete-first-field"
    }).appendTo($wrap);
    $("<i>", {
      class: "fa fa-search",
      "aria-hidden": true
    }).appendTo($field1);
    $("<div>", {
      class: "autocomplete-second-field three-dots"
    }).html(item.label).appendTo($wrap);
    return $item.appendTo(ul);
  };
});

有很多东西需要修复和改进。

让我们从Ajax开始。您正在调用一个MediaWiki API,并期望得到一些结果。当调用返回时,它将生成有关pilimit的警告。深入了解API文档,这是一个特定于pageimages属性调用的参数。要解决这个问题,prop值必须是extracts|pageimages。现在我得到了一组清晰的结果。

您可以看到,我释放了数据,以便更容易地进行更改,并查看我向API发送的参数。你的方法没什么问题,我只是觉得用起来容易多了。

当我们填充.autocomplete()时,这一切都发生在source内部。当我们使用function作为source时,它必须遵循以下几条准则:

  • 我们传递一个requestresponse
  • 结果必须在数组中。
  • 数组可以包含对象,只要它们至少包含{ label, value }
  • 我们的结果数组必须传递给response函数。

一个简单的例子:

代码语言:javascript
复制
$(selector).autocomplete({
  source: function(req, resp){
    var q = req.term;
    // The Request is an object that contains 1 index: term
    // request.term will contain the content of our search
    var results = [];
    // An array to store the results
    $.getJSON("myapi.php", {query: q}, function(data){
      $.each(data, function(key, val){
        // iterate over the result data and populate our result array
        results.push({
          label: data.name,
          value: data.url
        });
        resp(results);
      });
    });
  }
});

您可以对结果进行排序或筛选,只要您最终将结果传递给response

使用focusselect回调,您希望返回false。这里将更多地讨论这一点:http://jqueryui.com/autocomplete/#custom-data

我们还看到了一个呈现菜单项的很好的例子。我转而使用jQuery对象,而不是原始的HTML。你做对你最有效的事。

工作示例:https://jsfiddle.net/Twisty/vr6gv2aw/4/

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48476560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档