jquery ajax擷取json資料實現百度的搜尋提示

來源:互聯網
上載者:User


挺炫的一個效果,百度和Google好像已實現好多年了,我以為在網上能輕易找到代碼來實現這個效果。真正遇到這個需求,發現還真找不到。於是自己動手寫這個效果,由於我是把效果整合到我的整套架構裡,所以沒有進行單獨的封裝。

需求:
實現帶提示的input框,類似百度搜尋,有改動的時候去擷取常用關鍵詞,資料來源於系統資料庫,支援滑鼠選擇或鍵盤選擇

思路:
架構一貫思路,通過class作為監聽入口,通過data作為資料傳遞;
通過監聽input和propertychange事件實現即時的改動監聽,input是主流,propertychange是ie,你懂的;
通過ajax實現post動作,把返回內容顯示成類似選框的形式;
監聽鍵盤的上鍵(38)、下鍵(40)、斷行符號鍵(13),通過綁定keydown,判斷event.keycode實現;
監聽滑鼠的mouseover和click事件,與鍵盤動作要完美結合;
若input內容要求與已知選項必須一致,則監聽blur事件,判斷是否允許換焦點;

實現代碼:

//By COoL
 
//定義全域變數用於儲存提示層
var liketips;
 
//監聽改動或得到焦時間點事件
 
//禁用chrome和firefox瀏覽器內建的自動提示
$('.getsearchjson').attr("autocomplete","off");
$('.getsearchjson').bind("propertychange input focus",function(event){
    $this=$(this);
    if(event.type!='focus'){
        //如果有改變,則狀態定為必須重新選擇,因為純人手輸入會導致value無法插入
        $this.data('ok',false);
    }
 
    //擷取input框位置並計算提示層應出現的位置
    var top=1*$this.offset().top+25;
    var left=1*$this.offset().left;
    var width=1*$this.width()+12;
    
    //重建儲存提示層並讓其在適當位置顯示
    $(liketips).remove();
    liketips=document.createElement('div');
    $liketips=$(liketips);
    //class樣式這裡不提供,最主要是position:absolute
    $liketips.addClass("liketips");
    $liketips.css({top:top+'px',left:left+'px',width:width+'px'});
 
    //載入前先顯示loading動態圖
    $liketips.append('<img src="/images/loading.gif" border="0" />');
    $liketips.appendTo($this.parent());
    $liketips.show();
 
    //定義ajax去擷取json,type參數通過data-type設定,keyword則是目前已輸入的值
    //傳回值以table形式展示
    $.post('/data/search.do',{type:$this.data('type'),keyword:$this.val()},function(json){
        $liketips.empty();
        var htmlcode="<table cellspacing='0' cellpadding='2'><tbody>";
        for(var i=0;i<json.datas.length;i++){
            //這裡我需要用到value和title兩項,所以用data-value傳遞多一個參數,在斷行符號或滑鼠點擊後賦值到相應的地方,以此完美地替代select
            htmlcode+='<tr data-value="'+json.datas[i][0]+'"><td>'+json.datas[i][1]+'</td></tr>';
        }
        htmlcode+="</tbody></table><span>請務必在此下拉框中選擇</span>";
        //把loading動態圖替換成內容
        $liketips.html(htmlcode);
    },"json");
});
 
//焦點消失時確保資料來自選項,隱藏提示框體
$('.getsearchjson').blur(function(){
    //因為滑鼠點擊時blur動作結算在click之前,setTimeout是為瞭解決這個問題
    $oldthis=$(this);
    setTimeout(function(){
        if($oldthis.data('ok'))
            $(liketips).fadeOut('fast');
        else{
            alert('為保證資料準確性,請務必在下拉提示中選擇一項,謝謝合作');
            $oldthis.focus();
        }
    },200);
});
 
//監聽鍵盤動作
$('.getsearchjson').keydown(function(event){
    //console.log(event.keyCode);
    $this=$(this);
    if(event.keyCode==40){
        //按鍵是向下
        $nowtr=$('tr.selectedtr');
        //如果已存在選中,則向下,否則,選中選單中第一個
        if($nowtr.length>0){
            $nexttr=$nowtr.next('tr')
            //如果不是最後選項,向下個tr移動,否則跳到第一個tr
            if($nexttr.length>0){
                $('tr.selectedtr').removeClass();
                $nexttr.addClass('selectedtr');
            }
            else{
                $('tr.selectedtr').removeClass();
                $nowtr.parent().find('tr:first').addClass('selectedtr');
            }
        }
        else{
            $('.liketips').find('tr:first').addClass('selectedtr');
        }
    }
    else if(event.keyCode==38){
        //按鍵是向上
        $nowtr=$('tr.selectedtr');
        //如果已存在選中,則向下,否則,選中選單中第一個
        if($nowtr.length>0){
            $prevtr=$nowtr.prev('tr')
            //如果不是最後選項,向下個tr移動,否則跳到第一個tr
            if($prevtr.length>0){
                $('tr.selectedtr').removeClass();
                $prevtr.addClass('selectedtr');
            }
            else{
                $('tr.selectedtr').removeClass();
                $nowtr.parent().find('tr:last').addClass('selectedtr');
            }
        }
        else{
            $('.liketips').find('tr:last').addClass('selectedtr');
        }
    }
    else if(event.keyCode==13){
        //按鍵是斷行符號,則確定返回並隱藏選框
        $nowtr=$('tr.selectedtr');
        if($nowtr.length==1){
            //設定value值到input框通過參數data-valueto配置的value值儲存項中去,一般是hidden項
            $valuefield=$('input[name='+$this.data('valueto')+']');
            $valuefield.val($nowtr.data('value'));
            $this.val($nowtr.text());
            //設定狀態是從選項中選擇,允許blur
            $this.data('ok',true);
        }
        $(liketips).fadeOut('fast');
        return false;
    }
    //console.log(event.keyCode);
    return true;
});
 
//監聽滑鼠動作,mouseover改變選中項
$(document).delegate('.liketips td','mouseover',function(){
    $nowtr=$(this).parent();
    $nowtr.siblings('tr').removeClass();
    $nowtr.addClass('selectedtr');
});
 
//監聽滑鼠動作,click選定
$(document).delegate('.liketips td','click',function(){
    $nowtr=$(this).parent();
    if($nowtr.length==1){
        //取得該提示層對應的input框
        $inputfield=$nowtr.parent().parent().parent().siblings('input.getsearchjson');
 
        //設定value值到input框通過參數data-valueto配置的value值儲存項中去,一般是hidden項
        $valuefield=$('input[name='+$inputfield.data('valueto')+']');
        $valuefield.val($nowtr.data('value'));
        $inputfield.val($nowtr.text());
        //設定狀態是從選項中選擇,允許blur
        $inputfield.data('ok',true);
    }
    $(liketips).fadeOut('fast');
});


CSS這裡就不放出了,我的實現效果如下:

//禁用chrome和firefox瀏覽器內建的自動提示
$this.attr("autocomplete","off");

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.