我正在使用自动填充功能从多个来源获取建议,并将其显示为UI中的一个列表。当我打字时,建议显示出来,但当我将鼠标悬停在建议上时,我收到错误" TypeError:n未定义"。当我点击建议时出现错误" ui.item未定义"。
HTML页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery Autocomplete with Multiple Search Engines Suggestions</title>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript">
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
var self = this, currentCategory = "";
$.each( items, function( index, item ) {
if ( item.category != currentCategory ) {
ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
currentCategory = item.category;
}
self._renderItem( ul, item );
});
}
});
$(function(){ //page load
$("#q").focus(); //set focus to search field
$("#q").catcomplete({
source:"suggest.php",
minLength:2,
delay:10,
select: function(event, ui) {
window.location.assign(ui.item.searchUrl + ui.item.label);
//document.getElementById("q").value = ui.item.label
//$("#q").val(ui.item.value);
//$("#searchform").submit();
}
});
});
</script>
<style type="text/css">
.ui-autocomplete-category {
font-weight: bold;
font-size: 1em;
padding: .2em .2em;
margin: .4em 0 .2em;
line-height: 1.5;
color: #069;
border-bottom: 2px solid #069;
}
li.ui-autocomplete-category {
list-style-type: none;
}
</style>
</head>
<body>
<form id="searchform" name="form1" method="get" action="http://www.google.com/search">
Search:
<input name="q" id="q" type="text" size="40" />
<input name="submit" type="submit" value="Search" />
</form>
</body>
</html>
PHP脚本:
<?php
//Search term
$term = $_REQUEST['term'];
//Search Engine array
$searchEngines = array(
"Google" => array("http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&q=", "http://www.google.com/search?q="),
//"Bing" => array("http://api.bing.com/osjson.aspx?query=", "http://www.bing.com/search?q="),
//"Yahoo" => array("http://ff.search.yahoo.com/gossip?output=fxjson&command=", "http://search.yahoo.com/search?p="),
"Wikipedia" => array("http://en.wikipedia.org/w/api.php?action=opensearch&search=", "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search="),
//"Ebay" => array("http://anywhere.ebay.com/services/suggest/?q=", "http://shop.ebay.com/i.html?_nkw="),
"Amazon" => array("http://completion.amazon.com/search/complete?search-alias=aps&client=amazon-search-ui&mkt=1&q=", "http://www.amazon.com/s/field-keywords=")
);
//Combine Search Results
$searchArray = array();
foreach($searchEngines as $engine => $urls){
$url = $urls[0] . rawurlencode($term);
try{
//$json = file_get_contents($url);
$json = get_url_contents($url);
$array = json_decode($json);
$array = $array[1]; //$array[1] contains result list
if(count($array) > 0){
$array = getFormattedArray($array, $engine, $urls[1]);
$searchArray = array_merge($searchArray, $array );
}
} catch (Exception $e){ /* Skip the exception */ }
}
//Output JSON
header('content-type: application/json; charset=utf-8');
echo json_encode($searchArray); //Convert array to JSON object
//Format array to add category (search engine name)
function getFormattedArray($array, $engine, $searchUrl){
$newArray = array();
foreach($array as $a){
$newArray[] = array('label' => $a, 'searchUrl' => $searchUrl, 'category' => $engine);
}
return $newArray;
}
//Read URL contents
function get_url_contents($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$ip=rand(0,255).'.'.rand(0,255).'.'.rand(0,255).'.'.rand(0,255);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("REMOTE_ADDR: $ip", "HTTP_X_FORWARDED_FOR: $ip"));
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/".rand(3,5).".".rand(0,3)." (Windows NT ".rand(3,5).".".rand(0,2)."; rv:2.0.1) Gecko/20100101 Firefox/".rand(3,5).".0.1");
$html = curl_exec($ch);
curl_close($ch);
return $html;
}
?>
答案 0 :(得分:1)
我暂时将其添加为评论,而不是答案,我计划在完成此问题时对其进行更新。
首先,我能够在此处复制您的代码和错误:https://jsfiddle.net/xatu48sc/2/
我正在使用常规(非缩小)版本。我在第5836行遇到了错误:
5826 item = ui.item.data( "ui-autocomplete-item" );
5827 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5828
5829 // use value to match what will end up in the input, if it was a key event
5830 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5831 this._value( item.value );
5832 }
5833 }
5834
5835 // Announce the value in the liveRegion
5836 label = ui.item.attr( "aria-label" ) || item.value;
5837 if ( label && $.trim( label ).length ) {
5838 this.liveRegion.children().hide();
5839 $( "<div>" ).text( label ).appendTo( this.liveRegion);
5840 }
我看到的错误是:
TypeError:item is undefined jquery-ui.js(第5836行,第13栏)
这告诉我们item
未定义,因此item.value
未定义,因此我将代码包含在启动之前。这将指向我们返回您的自定义小部件以呈现类别。
当我将其与https://jqueryui.com/autocomplete/#categories处的示例进行比较时,我可以看到许多不同之处。没有_create
方法,在_renderMenu
方法中,没有为项目定义li
。
这里的某个地方就是问题所在。
我还发现只有没有类别的项目才会抛出此错误。
<强>更新强>
我通过使用文本比较网站在您的代码中发现了该问题。这是问题所在:
self._renderItem( ul, item );
示例页面中的命令是:
li = that._renderItemData( ul, item );
它没有使用_renderItem()
,但似乎是未记录的扩展点:_renderItemData()
基于此:Difference between jQuery autocomplete renderItem and renderItemData您正在使用扩展点。
当我对您的代码进行微小更改时,它可以正常运行:
$.widget("custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function(ul, items) {
var self = this, currentCategory = "";
$.each(items, function(index, item) {
var li;
if (item.category != currentCategory) {
ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
currentCategory = item.category;
}
li = self._renderItemData(ul, item);
});
}
});
工作示例:https://jsfiddle.net/xatu48sc/6/
我怀疑两者之间存在范围问题。如果这不好并且你真的想使用_renderItem()
那么我可以调查一下。使用_renderItemData()
确实有效。