在上一篇 jQuery打造智能提示插件 上改進,增加下拉按鈕,修復點擊下拉區域外不隱藏BUG
效果

下拉按鈕素材:
js封裝,注意紅色部分為BUG修復,然后傳入boxwidth不帶px:
/* /// <reference path="jquery-autocomplete2.0.js" /> zhangs 20140516 */ (function($) {
var KEY = {
UP: 38, DOWN: 40, DEL: 46, TAB: 9, RETURN: 13, //回車 ESC: 27, COMMA: 188, SPACE: 32, //空格 PAGEUP: 33, PAGEDOWN: 34, BACKSPACE: 8 }; //默認屬性 var defaults = { hidvalueid: "combox_hid_value", //保存選中元素值的input的ID boxwidth: 150, //文本框寬度,不帶px,暫不支付百分比 url: "", //提交的頁面/方法名,URL ="AsynHandler.ashx?ywtype=GetUserNameList" param: null//要發送到服務端參數格式,主要是要動態取值的參數:[{ keyname: "catalog", keyvalue: "txtCata" }, { keyname: "cba", keyvalue: "txtCata2"},……] };
$.fn.combox = function(options) { var options = $.extend(defaults, options); //將傳入的參數進行合並 var hidvalue = $("#" + defaults.hidvalueid); //選中的值 //實現功能 return this.each(function() { var cb = $(this); //輸入框 cb.width(defaults.boxwidth - 15).css({ "cursor": "pointer", "float": "left" }); var id = cb.attr("id"); var searchresultdiv = $("<div id='" + id + "_searchresult' style='display: none;' />").insertAfter(cb); searchresultdiv.addClass("searchresult").width(defaults.boxwidth); //創建img var img = $("<img id='" + id + "_img' style='cursor: pointer;float:left;'/>").insertAfter(cb); img.attr("src", 'src/images/select_arrow.gif'); // 默認箭頭 defaults.boxwidth = defaults.boxwidth + "px"; //重新設置為px img.click(function() { //顯示所有項 cb.val(" "); hidvalue.val(""); cb.keyup(); cb.focus(); }); //點擊非彈出框區域隱藏彈出框 $(document).mousedown(function() { if (searchresultdiv.css("display") == "block") { var mx = event.clientX + $(document).scrollLeft(); //在iframe中滾動距離 var my = event.clientY + $(document).scrollTop(); //clientY相對文檔的垂直座標 offsetY相對容器的垂直坐標 var x1 = searchresultdiv.offset().left; var y1 = searchresultdiv.offset().top; // 元素相對於document的上位移 var x2 = x1 + searchresultdiv.outerWidth(); var y2 = y1 + searchresultdiv.outerHeight(); if (mx < x1 || my < y1 || x2 < mx || y2 < my) { searchresultdiv.css("display", "none"); } } }); var strTmp = ""; if (defaults.url.indexOf("?") == -1) { strTmp += "?"; } else { strTmp += "&"; } cb.keyup(function(evt) { changeCoords(); //控制查詢結果div坐標 var k = window.event ? evt.keyCode : evt.which; //輸入框的id為txt_search,這里監聽輸入框的keyup事件 //不為空 && 不為上箭頭或下箭頭或回車 if (cb.val() != "" && k != KEY.UP && k != KEY.DOWN && k != KEY.RETURN) { var strTmp2 = ""; //拼接傳入的參數 if (defaults.param != null) { $.each(defaults.param, function(i, item) { if (typeof item.keyvalue != "string") { alert("控件參數格式有錯誤,請檢查"); return; } var value = $("#" + item.keyvalue).val(); if (value != "" || value != null) { strTmp2 += item.keyname + "=" + escape(value) + "&"; } }); } var sUrl = defaults.url + strTmp + strTmp2 + "key=" + escape(cb.val()) + "&rdnum=" + Math.random(); $.ajax({ type: 'GET', async: false, //同步執行,不然會有問題 dataType: "json", url: sUrl, //提交的頁面/方法名 //data: , //參數(如果沒有參數:null) contentType: "application/json; charset=utf-8", error: function(msg) {//請求失敗處理函數 alert("數據加載失敗"); }, success: function(data) { //請求成功后處理函數。 showlist(data); } }); } else if (k == KEY.UP) {//上箭頭 $('#' + id + '_combox_table tr.combox-hover').prev().addClass("combox-hover").width(defaults.boxwidth); $('#' + id + '_combox_table tr.combox-hover').next().removeClass("combox-hover"); var tr_box_hover = $('#' + id + '_combox_table tr.combox-hover'); if (tr_box_hover.position() != undefined) { if (tr_box_hover.position().top < 0) { //向上滾動遮住的部分+本身的高度+padding高度 searchresultdiv.scrollTop(searchresultdiv.scrollTop() - (tr_box_hover.height() - tr_box_hover.position().top + 4)); } cb.val($('#' + id + '_combox_table tr.combox-hover').text()); hidvalue.val($('#' + id + '_combox_table tr.combox-hover td').attr("value")); } } else if (k == KEY.DOWN) {//下箭頭 if ($('#' + id + '_combox_table tr.combox-hover').size() == 0) { $('#' + id + '_combox_table tr.combox-line:first').addClass("combox-hover").width(defaults.boxwidth); //若無選中的,則選中第一個 } else { $('#' + id + '_combox_table tr.combox-hover').next().addClass("combox-hover").width(defaults.boxwidth); $('#' + id + '_combox_table tr.combox-hover').prev().removeClass("combox-hover"); var tr_box_hover = $('#' + id + '_combox_table tr.combox-hover'); if (tr_box_hover.position().top + tr_box_hover.height() > searchresultdiv.height()) { //向下滾動遮住的部分+本身高度+padding高度 searchresultdiv.scrollTop(searchresultdiv.scrollTop() + tr_box_hover.height() + (tr_box_hover.position().top + tr_box_hover.height()) - searchresultdiv.height() + 4); } } cb.val($('#' + id + '_combox_table tr.combox-hover').text()); hidvalue.val($('#' + id + '_combox_table tr.combox-hover td').attr("value")); } else if (k == KEY.RETURN) {//回車 if ($('#' + id + '_combox_table tr.combox-hover').text() != "") { cb.val($('#' + id + '_combox_table tr.combox-hover').text()); hidvalue.val($('#' + id + '_combox_table tr.combox-hover td').attr("value")); } searchresultdiv.empty(); searchresultdiv.css("display", "none"); } else { searchresultdiv.empty(); hidvalue.val(""); //清空數據后也要清空值 searchresultdiv.css("display", "none"); } }); // searchresultdiv.bind("mouseleave", function() { // searchresultdiv.empty(); // searchresultdiv.css("display", "none"); // }); //根據data生成下拉列表 function showlist(data) { if (data == "false") { return; } if (data.length > 0) { var layer = ""; layer = "<table id='" + id + "_combox_table'>"; //layer += "<tr class='combox-line' style='width:" + defaults.boxwidth + "'><td style='width:" + defaults.boxwidth + "' value=''>請選擇</td></tr>"; $.each(data, function(idx, item) { layer += "<tr class='combox-line' style='width:" + defaults.boxwidth + "'><td style='width:" + defaults.boxwidth + "' value='" + item.Value + "'>" + item.Name + "</td></tr>"; }); layer += "</table>"; //將結果添加到div中 searchresultdiv.empty(); searchresultdiv.append(layer); //$(".combox-line:first").addClass("combox-hover"); //初始化時不能顯示,此時回車不會選中第一個 searchresultdiv.css("display", ""); //鼠標移動事件 $(".combox-line").hover(function() { $(".combox-line").removeClass("combox-hover"); $(this).addClass("combox-hover").width(defaults.boxwidth); }, function() { $(this).removeClass("combox-hover"); //searchresultdiv.css("display", "none"); }); //鼠標點擊事件 $(".combox-line").click(function() { cb.val($(this).text()); hidvalue.val($(this).children()[0].value); searchresultdiv.css("display", "none"); }); } else { searchresultdiv.empty(); searchresultdiv.css("display", "none"); } } //設置查詢結果div坐標 function changeCoords() { var left = cb.position().left; //獲取距離最左端的距離,像素,整型 var top = cb.position().top + 20; ; //獲取距離最頂端的距離,像素,整型(20為搜索輸入框的高度) searchresultdiv.css("left", left + "px"); //重新定義CSS屬性 searchresultdiv.css("top", top + "px"); //同上 } return cb; }); }; })(jQuery);
前台注意boxwidth不帶單位:
<link href="style/jquery-autocomplete2.0.css" rel="stylesheet" type="text/css" />
<script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-autocomplete2.0.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var strurl = "AsynHandler.ashx?ywtype=GetUserNameList";
$("#txt_search").combox({ hidvalueid: "hidselvalue",boxwidth:"150", url: strurl, param: [{ keyname: "catalog", keyvalue: "txtCata" }, { keyname: "cba", keyvalue: "txtCata1"}] });
$("#form1").keydown(function() {
//防止選中后回車提交表單
return (event.keyCode != 13);
});
});
</script>
后台不變
