我用如下JS代码获取百度搜索下拉框关键字,为什么会时灵时不灵?
麻烦大家帮我看下,如图获取百度搜索热词,在自己站点上显示下拉选项实现搜索。如下代码可以实现,但是会时灵时不灵,尚且不知道是哪里出了问题。
调试时发现,出现问题的时候, jsonp 正常请求没问题。但回调函数不是每次都会按预期的结果正常执行。
测试浏览器 360极速浏览器 极速模式。
在线Demo : http://hxy100.gitcafe.io/gh-demos/baidu-suggest/demo.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>中国微商第一新媒体-微商创业,运营,推广,管理者学习交流平台-商贾之家</title>
<meta name="description" content="{$SEO['description']}"/>
<meta name="keywords" content="{$SEO['keyword']}"/>
<link rel="stylesheet" type="text/css" href="css/swiper3.1.0.min.css"/>
<link rel="stylesheet" type="text/css" href="css/common_weishang.css"/>
<script type="text/javascript" src="js/jquery.weishang.js"></script>
<style type="text/css">
#sugdiv{
z-index: 999;
background-color: #FAF2F2;
width:380px;
position:absolute;
}
#sugdiv ul li {
height:35px;
line-height: 35px;
font-size:16px;
margin: 0px;
padding-left: 6px;
text-align: left;
white-space:nowrap;
}
#sugdiv ul li:hover{
background-color: #D5F2DE;
cursor: pointer;
}
</style>
</head>
<body>
<div class="header">
<div class="header_inner">
<img src="images/logo.png" alt="商贾之家-微商第一新媒体"/>
<div class="left_search">
<div>
<form action="http://www.baidu.com/s?wd=" method="get" target="_blank">
<a class="js_setHome sethome g_red" onclick="window.SetHome(this,'')" href="" hidefocus="true">设为首页</a>
<span>|</span>
<a href="{APP_PATH}/tougao.html" target="_blank">我要投稿</a>
<input type="hidden" value="67063059_pg" name="tn"/>
<p><input id="searchwd" name="wd" type="text" value=""/> <button onclick="$(this).closest('form').submit()">百度一下</button></p>
</form>
<div id="sugdiv" style="">
<ul>
</ul>
</div>
<script type="text/javascript">
function getBDJson(jsondata){
var sugdiv =$('#sugdiv'),html="";
var suges=jsondata['s'];
if(suges.length==0){
$(sugdiv).hide();
return;
}
$(sugdiv).hide().children('ul').empty();
for (var i = 0; i < suges.length; i++) {
html+='<li onclick="BDsearch(this)">'+ suges[i]+'</li>';
}
$(sugdiv).children('ul').html(html);
$(sugdiv).css('top',$('#searchwd').offset().top+$('#searchwd').height()+'px').css('left',$('#searchwd').offset().left+'px');
$(sugdiv).css('display','block').show();
return jsondata;
}
function BDsearch(obj) {
var wd = $(obj).text();
$('#sugdiv').hide();
$('#searchwd').val(wd).closest('form').submit();
}
$('#searchwd').keyup(function(){
if($(this).val()==""){
$('#sugdiv').hide();
return true;
}
var word = $(this).val();
$.ajax({
type : "get",
async:false,
url : "http://suggestion.baidu.com/su?",
dataType : "jsonp",
jsonp: "callbackparam",
jsonpCallback:"getBDJson",
data:{
wd:word,
cb:"getBDJson"
},
success : function(json){
},
error:function(){}
});
});
$(document).click(function(event) {
if($('#sugdiv').is(':visible')){
$('#sugdiv').hide();
}
});
</script>
</div>
</div>
</div>
</div>
</body>
</html>
jquery autocomplete HTML JavaScript
坦桑尼亚造船厂
9 years, 5 months ago
Answers
问题是在两次紧接着的DOM操作间会产生一个race condition,在前一次DOM完成之前下一次紧接着开始了。
$(sugdiv).hide().children('ul').empty(); - 1
$(sugdiv).children('ul').html(html); - 2
最简单的优化是去掉第1句,剩第二句,就没有race condition了。
但是这样设计还有缺陷,应该考虑对keyup的handler进行debounce,并且把getDBJson调用重构成异步执行_.defer或者_.delay,这样更新列表对敲击键盘的体验的影响可以减到最小。
秘技的DOM操作应该用尽可能快的调用,比如用document.getElementById替代$('#..'),用.innerHTML=...替代.html(...),应该避免不必要的hide()调用。
超级无敌大烤鸭
answered 9 years, 5 months ago