在网页中实现 ComboBox 的组件化

HTML 只提供了文本框和下拉列表框,没有提供 ComboBox 控件。虽然可以通过并排显示文本框和下拉列表框,并以脚本控制其关联的方法实现,但显示效果的确不理想。于是大家都想办法解决。综合了一下,现有的实现方法有两种思路:

1、用文本框加 Img 或 div 的方法,在点击时通过脚本控制某个层的显示状态。优点是可定义非常好的显示效果,也可实现非常复杂的功能。比如和数据库关联,显示树型的结构或多列的记录结构等。缺点是太复杂,不容易使用控制。

2、用文本框加下拉列表框实现,通过CSS将两个控件组合成 ComboBox 的外观,再用脚本实现联动。优点是简单易用,缺点是只能显示单行的列表,不能实现复杂的功能。

考虑到常用的功能,还是用第 2 种方法较为方便。在网上找了一些,虽然实现了这个效果,但使用起来比较麻烦。比如页面上有很多个这样控件时,工作量就太大了,而且维护修改起来不太方便。还是自己动手吧。

如果网站上有十个网页需要用到 ComboBox 控件,每个页面上又同时有十个存在,我想总不能一个一个的写一百遍吧?而且每一个的内容、宽度、ID都不同,即使将代码复制过去还需要大量的修改,这样的工作量可想而知。所以,这里的关键是如何将其组件化,以使在使用的时候最方便化,并且在修改时只修改组件即可。

那么如何组件化呢?自然而然想到了 HTC !

 

先来看看最终效果:

 

实现思路:ComboBox 控件的主要部分还是文本框,下拉列表框只是提供一个侯选的列表。所以我们以文本框为主,由 HTC 负责为其添加下拉列表框。使用时只要为文本框指定一个 combobox 的样式,再多写一个以逗号分隔的字符串作为下拉列表的内容就行了。如:

< input  type ="text"  class ="combobox"  items ="aaa,bbb,ccc,ddd,eee" />

这个 combobox 样式定义为:

input.combobox {
    behavior
: url(combobox.htc) ;
}

combobox.htc 内容如下:

< public:component >
    
< public:attach  event ="ondocumentready"  onevent ="init()"   />
    
< public:property  name ="items" />

    
< script  type ="text/javascript" >
        
function  init(){
            
if (items != null ){
                items 
=  items.replace( / ( ^ s * ) | (s * $) / g,  "" ); 
                
if  (items  !=   '' ) {
                    
var  arritem  =  items.split( ' , ' );
                    
var  selcon  =  document.createElement( ' select ' );
                    selcon.options.add(document.createElement(
" option " ));
                    
for ( var  i = 0 ;i < arritem.length;i ++ ){
                        
var  oOption  =  document.createElement( " option " );
                        
var  text  =  arritem[i];
                        
if (text != '' )text  =  text.replace( / ( ^ s * ) | (s * $) / g,  "" ); 
                        oOption.text 
=  text;
                        oOption.value 
=  text;
                        selcon.options.add(oOption);
                    }
                    selcon.style.position 
=   ' absolute ' ;
                    selcon.style.width 
=  element.clientWidth  +   20   +   ' px ' ;
                    selcon.style.clip 
=   ' rect(auto auto auto  '   +  element.clientWidth  +   ' px) ' ;
                    selcon.style.marginTop 
=   ' 1px ' ;
                    selcon.onchange
= function (){
                        element.value 
=   this .value;
                        element.select();
                        element.focus();
                    }
                    
var  parent  =  element.parentNode;
                    parent.insertBefore(selcon,element);
                }
            }
        }
    
</ script >
</ public:component >

所有需要使用 ComboBox 的地方,使用普通的文本框即可,只要定义样式为 combobox,并且 items 属性不为空,它就会显示为下拉框。是不是很好用呀?! 而且再为它定义方法,就很容易实现列表的添加修改和删除功能了。

 

不过不要高兴的太早,HTC虽然是个好东西,但目前只有 IE 支持,也就是说,在非 IE 浏览器里显示的还是一个正常的文本框。

即然如此,那就用另外一种方法来解决兼容性问题。将下面的函数 ComboBox 在 window.onload 里调用即可,它会查找所有样式为 combobox 的文本框,并为它们添加下拉列表

function  ComboBox(){
    
var  inputs  =  document.getElementsByTagName( ' input ' );
    
var  comboboxs  =   new  Array;
    
for ( var  i = 0 ;i < inputs.length;i ++ ){
        
var  item  =  inputs[i];
        
if (item.type  ==   ' text '   &&  item.className  ==   ' combobox ' )
            comboboxs[comboboxs.length] 
=  item;
    }
    
if (comboboxs.length > 0 ){
        
for ( var  i = 0 ;i < comboboxs.length;i ++ ){
            
var  combobox  =  comboboxs[i];
            
var  items  =  combobox.getAttribute( ' items ' );
            
if  (items  !=   null ) {
                items 
=  items.replace( / ( ^ s * ) | (s * $) / g,  "" );
                
if  (items  !=   '' ) {
                    
var  arritem  =  items.split( ' , ' );
                    
var  selcon  =  document.createElement( ' select ' );
                    selcon.options.add(document.createElement(
" option " ));
                    
for  ( var  j  =   0 ; j  <  arritem.length; j ++ ) {
                        
var  oOption  =  document.createElement( " option " );
                        
var  text  =  arritem[j];
                        
if  (text  !=   ''
                            text 
=  text.replace( / ( ^ s * ) | (s * $) / g,  "" );
                        oOption.text 
=  text;
                        oOption.value 
=  text;
                        selcon.options.add(oOption);
                    }
                    selcon.style.position 
=   ' absolute ' ;
                    selcon.style.width 
=  combobox.clientWidth  +   20   +   ' px ' ;
                    selcon.style.clip 
=   ' rect(auto auto auto  '   +  combobox.clientWidth  +   ' px) ' ;
                    
if (document.all  &&  window.external)selcon.style.marginTop  =   ' 1px ' ;
                    selcon.onchange 
=   function (){
                        
var  input  =   this .nextSibling;
                        input.value 
=   this .value;
                        input.select();
                        input.focus();
                    }
                    
var  parent  =  combobox.parentNode;
                    parent.insertBefore(selcon, combobox);
                }
            }            
        }
    }
};

 

实现过程:

怎样将文本框和下拉列表组合?

从理论上讲,只要将文本框和下拉列表框“紧紧的”并排挤在一起,并将下拉列表框的宽度减小到只留下一个下拉箭头,就和 ComboBox 的外观相同了。
但是,在 IE 中,下拉列表框的宽度减小了,点击下拉箭头展开的列表的宽度也跟着减小了,看不到内容了;而在非 IE 中,下拉列表框的宽度小于下拉箭头的宽度时就会隐藏下拉箭头,也不是我们想要的效果,所以不能用这种方法。
好在 CSS 中提供了 clip 的样式,它可以设置对象的可视区域,而且可视区域外的部分是透明的。这样就符合我们的要求了:将下拉列表框除下拉箭头外都隐藏起来!
但当把 clip 样式赋给下拉列表框后,却没有任何效果!原来, clip 样式只会在 position 样式的为 absolute ,即对象为绝对定位方式时才会起作用。
当赋予下拉列表框绝对定位样式后,需要把它的代码放在文本框代码之前,这样两个控件就会重合,再把下拉列表框的宽度定为文本框加上下拉箭头的宽度,再将文本框宽度的部分隐藏,就完美组合成了 ComboBox 控件。

清楚了组合方法,代码就容易写了。动态创建下拉列表框,插入文本框前面,再设置样式,添加事件以实现两个控件关联。上面两种方法的基本代码相同,都是这一过程。

 

HTC 方法在 IE6、IE7下测试通过;没有 IE 5.5 无法测试,IE 5.5 以下版本不支持 HTC
函数方法在 IE6、IE7、Opera 9.2、Firefox 1.5、Firefox 2.0下测试通过。

<script type="text/javascript"> function ComboBox(){var inputs = document.getElementsByTagName('input');var comboboxs = new Array;for(var i=0;i 0){for(var i=0;i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值