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

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

// 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) { ... });之外getAutocompleteResults(function(d) { ... }); function。

但是,源应该是动态的,而不是静态数组。 换一种说法:

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

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

 $(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; } 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 $("
  • ") .append( '
    ' + item.label + "
    " ) .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 nepadarytų tik vieno rezultato todėl paliekam laikinai ;) } }; $("input").on("keydown", changeText1); $("input").on("input", function(e) { $("#instant-search").text($("#search").val()); }); });
  •  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%; } } 
         

    编辑1经过一些更改后,会在ajax调用之前显示结果。 如何在成功完成ajax之后才使用response() (尝试使用success回调,不起作用:()?

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


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

    1. 刚刚重新加载页面时的样子: 在此处输入图像描述
    2. 让我们尝试输入“a”: 在此处输入图像描述
    3. 我们得到了一些结果。 好吧,让我们试着点击“无政府主义象征主义”元素: 在此处输入图像描述
    4. 结果应该看起来像“无政府主义象征主义”搜索。 但是,它返回“a”搜索的结果。 如果我们按下“fraktur”元素怎么办? 在此处输入图像描述
    5. 现在它显示了我们之前搜索的“无政府主义象征主义”结果。 但是,它应该返回“fraktur”搜索的元素。

    编辑2我修复了很多东西,并从我的代码中删除了一些非常无意义的东西。 但是,ajax调用的情况仍然相同。

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

    有任何想法吗?

    编辑3修正了ajax滞后(现在只有在前一个ajax调用之后才会发送ajax请求)。

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

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

    首先,我们将检查HTML。 有一些结束标签丢失。

    HTML

      

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

    我没有对CSS或Style进行任何更改。

    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 = $("
  • "); var $wrap = $("
    ").appendTo($item); var $field1 = $("
    ", { class: "autocomplete-first-field" }).appendTo($wrap); $("", { class: "fa fa-search", "aria-hidden": true }).appendTo($field1); $("
    ", { 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的参数。 你的方法没有错,我发现这更容易使用。

    当我们填充source时,这一切都发生在.autocomplete()内部。 当我们使用function作为source ,它必须遵循一些指导原则:

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

    一个简短的例子:

     $(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/

    希望这可以帮助。