手记

原生JS实现下拉列表选择、赋值

1、index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js实现下拉选择</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <script type="text/javascript" src="js/eventUtil.js"></script>
    <script type="text/javascript" src="js/script.js"></script>
</head>
<body>
    <div id="outDiv">
        <span>请选择分类</span>
        <ul id="ul">
            <li>ASP开发</li>
            <li>.Net开发</li>
            <li>PHP开发</li>
            <li>Javascript开发</li>
            <li>Java特效</li>
        </ul>
    </div>
</body>
</html>

2、css/style.css

*{
    margin: 0;
    padding: 0;
}
#outDiv{
    margin:100px auto;
    width: 200px;
}
#outDiv span{
    display:block;
    height:25px;
    line-height: 25px;
    font-size: 13px;
    padding-left: 5px;
    border:1px solid;
    background: url(../images/xjt.png) no-repeat right;
    cursor: pointer;
}
#outDiv ul{
    border: 1px solid;
    border-top: none;
    height: 125px;
    display: none;
}
#outDiv ul li{
    list-style-type: none;
    height: 25px;
    line-height: 25px;
    padding-left: 5px;
    cursor: pointer;
    font-size: 13px;
}

3、js/eventUtil.js

//使用变量,类似JSON类型的js对象方式进行事件处理程序的相关逻辑封装,主要解决了浏览器兼容性问题
//单独写进js中,便于html多次进行调运
var eventUtil = {
    //添加事件
    addEventHandle:function(element,eventType,fn){
        if(element.addEventListener){//非IE
            element.addEventListener(eventType,fn,false);
        }else if(element.attachEvent){//IE
            element.attachEvent('on'+eventType,fn);//这里拼接上'on',调运的时候不要加on,使用click等。
        }else{//不支持DOM2级,使用DOM0级方式
            element['on'+eventType] = fn;//这里使用[]方式实现对象的属性添加,相当于.的作用
        }
    },
    //删除事件
    removeEventHandle:function(element,eventType,fn){
        if(element.removeEventListener){//非IE,不带'on'
            element.removeEventListener(eventType,fn,false);//这里传入fn,是因为DOM2级或DOM0级都可以一次给一个元素的同一个事件绑定多个程序,所以需要传入具体的程序fn进行删除
        }else if(element.detachEvent){//IE,带'on'
            element.detachEvent('on'+eventType,fn);
        }else{//不支持DOM2级,使用DOM0级方式
            element['on'+eventType] = fn;
        }

    },
    //获取事件对象
    getEvent:function(event){
       return event?event:window.event;
    },
    //获取事件类型
    getType:function(event){
        event = event?event:window.event;
        return event.type;
    },
    //获取执行事件的目标元素
    getTarget:function(event){
        event = event?event:window.event;
        return event.target||event.srcElement;
    },
    //禁用默认行为
    preventDefault:function(event){
        event = event?event:window.event;
        if(event.preventDefault){
            event.preventDefault();//非IE
        }else{
            event.returnValue = false;//针对IE
        }

    },
    //阻止传播冒泡
    stopPropagation:function(event){
        event = event?event:window.event;
        if(event.stopPrapagation){
            event.stopPrapagation();//非IE
        }else{
            event.cancelBubble = true;//针对IE
        }
    }
}

4、js/script.js

/**
结合鼠标和键盘事件实现下拉列表的选择,赋值过程
难点:鼠标、键盘事件的逻辑衔接
注意一点:键盘事件document.onkeyup是在txtElement.onclick事件内部的,
意味着只有点击倒三角,下拉列表显示出来,才进行键盘事件的逻辑注册
*/
window.onload = function(){
    var outDiv = document.getElementById('outDiv'),
        txtElement = outDiv.getElementsByTagName('span')[0];
        selectUl = document.getElementById('ul'),
        selectLis = selectUl.getElementsByTagName('li'),
        selectIndex = -1;
    //展开选择列表
    txtElement.onclick = function(event){
        selectUl.style.display = 'block';
        eventUtil.stopPropagation(event);
        //绑定键盘事件:选择列表打开的情况下,上键实现上移(38)、下键实现下移(40)、回车键(13)实现选择
        document.onkeyup = function(event){
            event = event?event:window.event;
            var keyCode = event.keyCode;
            for (var i = 0; i < selectLis.length; i++) {
                selectLis[i].style.background = 'none';
            }
            if(keyCode == 38){//上移
                if(selectIndex<=0){
                    selectIndex = selectLis.length-1;
                }else{
                    selectIndex--;
                }
            }
            if(keyCode == 40){//下移
                if(selectIndex<0||selectIndex==selectLis.length-1){
                    selectIndex = 0;
                }else{
                    selectIndex++;
                }
            }
            selectLis[selectIndex].style.background = '#ccc';
            //回车键选择条目并关闭列表
            if(keyCode == 13 && selectIndex!=-1){
                event = event?event:window.event;
                txtElement.innerHTML = selectLis[selectIndex].innerHTML;
                selectUl.style.display = 'none';
                selectLis[selectIndex].style.background = 'none';
                selectIndex = -1;
            }
        }
        }
    //关闭选择列表
    document.onclick = function(){
        selectUl.style.display = 'none';
    }
    //选择列表事件:1、移入移出背景色 2、onclick:关闭列表,给span赋值,需要阻止冒泡,因为外层div点击需要展开
    for (var i = 0; i < selectLis.length; i++) {
        selectLis[i].index = i;
        selectLis[i].onmouseover = function(){
            if(selectIndex!=-1){
                selectLis[selectIndex].style.background = 'none';//清空键盘事件产生的样式
            }
            selectIndex = this.index;//通过鼠标事件重新设置选中索引
            this.style.background = '#ccc';         
        }
        selectLis[i].onmouseout = function(){
            this.style.background = '#fff';
        }
        selectLis[i].onclick = function(){//这里没有阻止冒泡,是为了使用document.onclick逻辑
            txtElement.innerHTML = this.innerHTML;
        };
    }
}

5、/images/xjt.png

4人推荐
随时随地看视频
慕课网APP