基于jQuery的select控件

曹华荣
2023-12-01

 自已开发的模拟select控件。实现了联想功能,并能很容易的组成及联下拉框。

废话少说,代码呈上。

 

代码下载地址:http://download.csdn.net/source/1779240

 

/**
 * jquery.myselect.js
 *
 * @author jiamiao
 */
(function($) {
 $.fn.extend({
  myselect : function(p) {
   p = $.extend({
    getoptionfun : false,// 外部传入的数据
    callback : false// 回调函数,在选中某列后触发
    }, p);
   return this.each(function(i, selectObj) {

    // 得到原select的名字
    var selectName = null;
    if (selectName == null)
     selectName = $(this).attr("name");

    // 生产模拟的select代码
    $(this).hide().after("<span class=/"myselectBorder/">"
      + "<input class=/"myselect/" type=/"text/" name=/""
      + selectName + "_show/" id=/"" + selectName
      + "_show/" size=/"24/"/>"
      + "<input type=/"hidden/" name=/"" + selectName
      + "/" id=/"" + selectName + "/" /><span id=/""
      + selectName + "_option/"></span></span>"
      + "<img class=/"myselect-trigger myselectImage/" id=/""
      + selectName + "_image/" src=/"image/s.gif/"/>");

    // 从select里直接得到或者从方法里得到
      
    var _option = new Array();
    if($.myselect.getSelectOption($(selectObj)) && $.myselect.getSelectOption($(selectObj)).length > 0){
     _option = $.myselect.getSelectOption($(selectObj));
    }
    else if(p.getoptionfun() && p.getoptionfun().length > 0){
     _option = p.getoptionfun();
    }

    // 将_option转化为json串置入隐藏区域
    // 其设计目的地在于可以从外部改变下拉列的值,方便增、删、改、排序等
    $("#" + selectName + "_option").hide().html($
      .obj2jsonstr(_option));

    $.each(_option, function(i) {
       if (i == 0) {
        $("#" + selectName + "_show").val(this.name);
        $("#" + selectName).val(this.value);
       }
       if (this.selected == true
         && $("#" + selectName).val() != this.value) {
        $("#" + selectName + "_show").val(this.name);
        $("#" + selectName).val(this.value);
       }
      });

    $("#" + selectName + "_show").each(function(i, input) {

     if ($.browser.mozilla) {
      // 根据FF调整文本框样式
      $(this).css("border-width", "1px 1px 1px 1px");
      $(this).parent().css("border", "0px");
     }

     $(this).blur(function(e) {// 为文本框添加失去焦点事件:当失去焦点时,删除下拉列
        if ((e.currentTarget || document.activeElement).id != "myselect_div_"
          + selectName
          && (e.currentTarget || document.activeElement).id != selectName + "_show"
          && $("#myselect_div_" + selectName)
            .size() > 0) {
         $("#myselect_div_" + selectName).remove();
        }
       }).keyup(function(e) {// 为文本框添加键盘按下事件:当键盘按下时,匹配相应的字段

        $("#myselect_div_" + selectName).remove();
        // 模拟点击下拉图片
        $.myselect.createOptions(selectObj, p);

        // 得到原select的下拉列
        var _alloption = eval($("#" + selectName
          + "_option").html());

        $("#myselect_div_" + selectName).show();
        
        // 匹配下拉列
        $.each(_alloption, function() {
         if (this.name.indexOf($(input).val()) == -1) {
          $("div[value=" + this.value + "]",
            "#myselect_div_" + selectName)
            .remove();
         }
        });
        
        //当按下向下的按钮的时候
        if (e.keyCode == 40) {
         $("#myselect_div_" + selectName).get(0).focus();
         $("div:first", $("#myselect_div_" + selectName)).addClass("ui-state-hover").css("cursor", "pointer");
        }
        
       });
    });

    // 为下拉列图片添加事件
    $(this).next().next(".myselectImage").each(function(i, img) {
     if ($.browser.mozilla) {
      // 根据FF调整图片位置
      $(this).css("margin", "0px 0px -10px -2px");
     }

     $(this).hover(function() {// 添加鼠标经过事件
        $(this).removeClass("myselect-trigger");
        $(this)
          .addClass("myselect-trigger-over");
       }, function() {
        $(this).addClass("myselect-trigger");
        $(this)
          .removeClass("myselect-trigger-over");
       }).click(function() {// 点击图片事件
        $.myselect.createOptions(selectObj, p);
        $("#myselect_div_" + selectName).get(0).focus();
       });
    });

    $(this).remove();// 删除原select
   });
  }
 });

 $.myselect = {
  // 得到原select的内容
  getSelectOption : function(obj) {
   var optionArray = new Array();
   $("option", $(obj)).each(function() {
      optionArray.push({
         name : $(this).text(),
         value : $(this).attr("value"),
         selected : $(this).attr("selected")
        });
     });
   return optionArray;
  },
  //修改文本框
  setSelect: function(id, name, value){
   $("#" + id + "_show").val(name);
   $("#" + id).val(value);
  },
  //得到文本框的值
  getSelect : function(id) {
   return {
    name : $("#" + id + "_show").val(),
    value : $("#" + id).val()
   }
  },
  //修改临时下拉列
  setTempOption : function(id, data) {
   $("#myselect_div_" + id).empty();
   $.each(data, function(i, n) {
      var _selected = "";
      if (this.selected == true) {
       _selected = "selected";
      }
      $(divObj).append("<div value='" + this.value + "' "
        + _selected + " title=/"" + this.name + "/">"
        + this.name + "</div>");
     });
  },
  // 得到临时下拉列
  getTempOption: function(id){
   var optionArray = new Array();
   $("div","#myselect_div_" + id).each(function(){
    optionArray.push({
         name : $(this).text(),
         value : $(this).attr("value"),
         selected : $(this).attr("selected")
        });
   });
   return optionArray;
  },
  //修改真正的下拉列
  setOption : function(id, data) {
   $("#" + id + "_option").html($.obj2jsonstr(data));
  },
  //得到真正的下拉列
  getOption : function(id) {
   return eavl($("#" + id + "_option").html());
  },
  createOptions : function(selectObj, p) {
   try {
    // 得到原select定义的相关事件
    var funArray = new Array();
    if ($.browser.mozilla) {
     // 根据FF添加onchange事件
     funArray.push(selectObj.onchange);
    } else {
     for (var p in selectObj) {
      if (typeof(selectObj[p]) == "function") {
       funArray.push(selectObj[p]);
      }
     }
    }

    var selectName = null;
    if (selectName == null)
     selectName = $(selectObj).attr("name");

    var img = $("#" + selectName + "_image");

    if ($("#myselect_div_" + selectName).size() == 0) {
     // 切换样式
     if ($(img).hasClass("myselect-trigger"))
      $(img).removeClass("myselect-trigger");
     if (!$(img).hasClass("myselect-trigger-click"))
      $(img).addClass("myselect-trigger-click");

     // 生成下拉列DIV
     $(img).after("<div class=/"myselect_div/" id=/""
       + "myselect_div_" + selectName + "/"></div>");

     var divObj = $("#myselect_div_" + selectName);

     divObj.css("left", $(img).prev().offset().left + "px").css(
       "width",
       $(img).prev().children("input").width() + 7 + "px");

     //divObj.focus();// 下拉列被选中

     // 下拉列带滚动条且生成失去焦点事件
     $(divObj).css("overflow", "auto").blur(function(e) {
      if ((e.currentTarget || document.activeElement).id != selectName
        + "_show")
       $(divObj).remove();

      // 切换图片样式
      if (!$(img).hasClass("myselect-trigger"))
       $(img).addClass("myselect-trigger");
      if ($(img).hasClass("myselect-trigger-click"))
       $(img).removeClass("myselect-trigger-click");
     });

     // 从隐藏的区域中得到下拉列的数据
     var _option = eval($("#" + selectName + "_option").html());
     // 为下拉列添加数据
     $.each(_option, function(i, n) {
        var _selected = "";
        if (this.selected == true) {
         _selected = "selected";
        }
        $(divObj).append("<div value='" + this.value
          + "' " + _selected + " title=/""
          + this.name + "/">" + this.name
          + "</div>");
       });

     // 为每一个元素加入提示
     //$("div", divObj).tooltip();

     // 计算下拉列的高度
     var _height = 0;
     if (_option.length <= 10) {
      _height = $("div:first", divObj).height()
        * _option.length;
     } else {
      _height = $("div:first", divObj).height() * 10;
     }
     divObj.css("height", _height + 2 + "px");

     // 计算下拉列的显示位置。当下面的高度不够时在文本框上方显示
     var browserWidth = window.innerWidth
       || document.documentElement.clientWidth
       || document.body.clientWidth;
     var browserHeight = window.innerHeight
       || document.documentElement.clientHeight
       || document.body.clientHeight;

     var wwidth = browserWidth || $(window).width();// 窗口的宽
     var wheight = browserHeight || $(window).height();// 窗口的高

     var scrollX = document.body.scrollLeft
       || document.documentElement.scrollLeft;// 横向滚动条的偏移量
     var scrollY = document.body.scrollTop
       || document.documentElement.scrollTop;// 纵向滚动条的偏移量

     if (wheight - ($(img).prev().offset().top - scrollY) >= _height) {
      // 显示在下方
      var divOffset = 0;
      if ($.browser.msie) {
       // IE的偏移量
       divOffset = 24;
      } else if ($.browser.mozilla) {
       // FF的偏移量
       divOffset = 8;
      }
      divObj.css("top", $(img).prev().offset().top
          + divOffset + "px");

     } else if (wheight - ($(img).prev().offset().top - scrollY) < _height) {
      // 显示在上方
      var divOffset = 0;
      if ($.browser.msie) {
       // IE的偏移量
       divOffset = 5;
      } else if ($.browser.mozilla) {
       // FF的偏移量
       divOffset = 21;
      }
      divObj.css("top", $(img).prev().offset().top - _height
          - divOffset + "px");
     }

     // 为下拉列的首项添加样式
     $("div:first", divObj).addClass("ui-state-hover").css(
       "cursor", "pointer");

     $("div", divObj).hover(function() {// 为下拉列添加鼠标经过事件
        $(this).siblings()
          .removeClass("ui-state-hover");
        if (!$(this).hasClass("ui-state-hover"))
         $(this).addClass("ui-state-hover").css(
           "cursor", "pointer");
       }, function() {
        if ($(this).hasClass("ui-state-hover"))
         $(this).removeClass("ui-state-hover").css(
           "cursor", "pointer");
       }).mousedown(function(e) {// 点击下拉列的事件
       // 为文本框和隐藏域赋值
       $(img).prev().children("input:frist")
         .val($(this).text());
       $(img)
         .prev()
         .children("input:last[type=hidden]")
         .val($(this).attr("value"));

       // 切换图片样式
       if (!$(img).hasClass("myselect-trigger"))
        $(img).addClass("myselect-trigger");
       if ($(img).hasClass("myselect-trigger-click"))
        $(img).removeClass("myselect-trigger-click");

       // 删除下拉列
       $(divObj).remove();

       // 执行原SELECT的方法
       $.each(funArray, function(i, n) {
          if (n)
           n(e);
          if (p.callback)
           p.callback($(this).attr("value"));
       });
      });

     $(divObj).keyup(function(e) {
      // 为下拉列添加键盘响应
      if (e.keyCode == 38) {
       // 向上按钮
       if ($(".ui-state-hover", divObj).prev().size() > 0) {
        $(".ui-state-hover", divObj).removeClass()
          .prev().addClass("ui-state-hover");
       }
      } else if (e.keyCode == 40) {
       // 向下按钮
       if ($(".ui-state-hover", divObj).next().size() > 0) {
        $(".ui-state-hover", divObj).removeClass()
          .next().addClass("ui-state-hover");
       }
      } else if (e.keyCode == 13) {
       // 回车按钮
       $(img).prev().children("input:frist").val($(
         ".ui-state-hover", divObj).text());
       $(img).prev().children("input:last[type=hidden]")
         .val($(".ui-state-hover", divObj)
           .attr("value"));

       if (!$(img).hasClass("myselect-trigger"))
        $(img).addClass("myselect-trigger");
       if ($(img).hasClass("myselect-trigger-click"))
        $(img).removeClass("myselect-trigger-click");

       $(divObj).remove();

       $.each(funArray, function(i, n) {
          if (n)
           n(e);
          if (p.callback)
           p.callback($(".ui-state-hover",
             divObj).attr("value"));
         })
      }
     });
    }
   } catch (e) {
    alert(e.name + ":/n" + e.message);
   }
  }
 }

 $.obj2jsonstr = function(o) {
  var r = [];
  if (typeof o == "string")
   return "/""
     + o.replace(/([/'/"//])/g, "//$1").replace(/(/n)/g, "//n")
       .replace(/(/r)/g, "//r").replace(/(/t)/g, "//t")
     + "/"";
  if (typeof o == "undefined")
   return "undefined";
  if (typeof o == "object") {
   if (o === null)
    return "null";
   else if (!o.sort) {
    for (var i in o)
     r.push(i + ":" + $.obj2jsonstr(o[i]))
    r = "{" + r.join() + "}"
   } else {
    for (var i = 0; i < o.length; i++)
     r.push($.obj2jsonstr(o[i]))
    r = "[" + r.join() + "]"
   }
   return r;
  }
  return o.toString();
 }

 $(function() {
    $(".myselect").myselect();
   });

})(jQuery)

 

 

 

jquery.myselect.css

 

@charset "utf-8";
/* CSS Document */

@charset "utf-8";

/* CSS Document */
.myselectBorder {
 border-top: #b5b8c8 1px solid;
 border-right: #b5b8c8 0px solid;
 border-bottom: #b5b8c8 1px solid;
 border-left: #b5b8c8 1px solid;
 margin: 0px 0px 0px 0px;
 background: #b5b8c8;
 border-color: #b5b8c8;
 float: none;
 font-size: 0%;
 height: 24px;
}

.myselect_div {
 position: absolute;
 z-index: 1;
 border: outset 1px #000;
 background: #F9F9F9;
 padding-left: 5px;
 padding-right: 5px;
 padding-top: 3px;
 padding-button: 3px;
 filter: alpha(opacity = 90);
 opacity: 0.9;
}

.myselect {
 border-width: 0px 0px 0px 0px;
 height: 20px;
}

.myselectImage {
 margin: -10px 0px -5px -1px;
 width: 17px;
 height: 24px;
 overflow: hidden;
 cursor: pointer;
}

.myselect-trigger{
 background: url(../image/trigger.gif);
    background-position:-51px 0;
 border-bottom-color:#b5b8c8;
}

.myselect-trigger-over{
 background: url(../image/trigger.gif);
    background-position:-68px 0;
 border-bottom-color:#b5b8c8;
}

.myselect-trigger-click{
 background: url(../image/trigger.gif);
    background-position:-85px 0;
 border-bottom-color:#b5b8c8;
}

.ui-state-hover {
 border: 1px solid #79b7e7;
 background: #d0e5f5 50% 50% repeat-x;
 font-weight: bold;
 color: #1d5987;
 outline: none;
}

 

 

 

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" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
<title>mySelect</title>
<link href="css/jquery.myselect.css"  type="text/css" rel="stylesheet"/>
<link href="css/jquery-ui-1.7.2.custom.css" type="text/css" rel="stylesheet">

<script type="text/javascript" src="js/jquery-1.3.2.js"></script>
<script language="javascript" src="js/jquery.myselect.js"></script>
<style type="text/css">
body,td,th {
 font-size: 12px;
}
</style>
<script type="text/ecmascript">
$(function(){ 
 //请注意打开IE7兼容模式 <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 
 $("#select1").myselect();
 
 /*
  //getoptionfun:可以手工穿下拉列的值进去
  //callback:回调函数。在选中某一行后触发。可以用来做级联下拉框
  $("#select1").myselect({
   getoptionfun : function(event){
    var array = new Array();
    for(var i=0; i<5;i++) {
     array.push({      
       name : "name"+i,
       value : i,
       selected : i==2 ? true : false
     });
    }
    return array;
   },
   callback:function(value){
    alert("选中了:"+value);
    
    //级联修改别的下拉框
    //$.myselect.setOption("select2",[{name:"北京",value:1,selected:true}]);
   }
  });
  
  //修改文本框
  $.myselect.setSelect(id, name, value)
  
  //得到文本框的值
  $.myselect.getSelect(id)
  
  //修改临时下拉列
  $.myselect.setTempOption(id, data)
  
  // 得到临时下拉列
  $.myselect.getTempOption(id)
  
  //得到真正的下拉列
  $.myselect.getOption(id)
 */
});
</script>
</head>

<body>
<p>
  <!--
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  -->
  <select name="select1" id="select1" οnchange="alert('你好!')">
    <option value="1">test1</option>
    <option value="2">test2</option>
    <option value="3">test3</option>
    <option value="4">test4</option>
    <option value="5">test5</option>
    <option value="6">test6</option>
    <option value="7">test7</option>
    <option value="8">test8</option>
    <option value="9">test9</option>
    <option value="10">test10</option>
    <option value="11">test11</option>
    <option value="12">apple</option>
    <option value="12">must</option>
    <option value="12">ccc</option>
  </select>
</p>

  <input type="button" value="码" οnclick="alert($('body').html())">
</body>
</html>

 类似资料: