在网页中实现 ComboBox 的组件化

本文介绍了一种在HTML中实现ComboBox控件的方法,通过文本框与下拉列表的组合及脚本控制,实现在IE和非IE浏览器上的兼容显示。

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下测试通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值