我用如下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

我就想知道你是怎么绕过跨域的……

爱撒旦韩国ia answered 9 years, 5 months ago

问题是在两次紧接着的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

Your Answer