这是《锋利的JQ》里第5章的第一个实例,也算是最简单的实例吧,看效果:

<!doctype html>
<html>
<head>
<title>文本框得到失去焦点</title>
<script>
window.onload = function(){
    var reg = document.getElementById("regForm");
    var inputs = [];
    for(var i = 0; i < reg.elements.length; i++){
        if(reg.elements[i].tagName != "FIELDSET"){
            inputs.push(reg.elements[i]);
        }
    }
    for(var i = 0; i < inputs.length; i++){
        inputs[i].onfocus = function(){ 
            addClass("focus",this);
            if(this.value == this.defaultValue){
                this.value = "";
            }
        }
        inputs[i].onblur = function(){
            removeClass("focus",this);
            if(this.value == ""){
                this.value = this.defaultValue;
            }
        }
    }
}
function addClass(className,node){
    return node.className += " " + className;
}
function removeClass(className,node){
    eles = node.className.split(/\s+/);
    for(var i = 0,l = eles.length; i < l; i++){
        if(eles[i] == className){
            eles.splice(i,1);
        }
    }
    node.className = eles.join(" ");
    return node;
}
</script>
<style>
    body{ font:normal 12px/17px Arial;}
    div{ padding:2px;}
    input,textarea{ width:12em; border:1px solid #888;}
    .focus{ border:1px solid #f00; background:#fcc;}
</style>
</head>
<body>
    <form action="" method="post" id="regForm">
        <fieldset>
            <legend>个人基本信息</legend>
            <div>
                <label for="username">名称:</label>
                <input type="text" id="username" value="名称" />
            </div>
            <div>
                <label for="pass">密码:</label>
                <input type="password" id="pass" value="密码" />
            </div>
            <div>
                <label for="msg">详细信息:</label>
                <textarea id="msg" rows="2" cols="20">详细信息</textarea>
            </div>
<body>
</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" />
<title></title>
<style type="text/css">
    body{ font:normal 12px/17px Arial;}
    div{ padding:2px;}
    input,textarea{ width:12em; border:1px solid #888;}
    .focus{ border:1px solid #f00; background:#fcc;}
</style>
</head>
<body>
    <form action="" method="post" id="regForm">
        <fieldset>
            <legend>个人基本信息</legend>
            <div>
                <label for="username">名称:</label>
                <input type="text" id="username" value="名称" />
            </div>
            <div>
                <label for="pass">密码:</label>
                <input type="password" id="pass" value="密码" />
            </div>
            <div>
                <label for="msg">详细信息:</label>
                <textarea id="msg" rows="2" cols="20">详细信息</textarea>
            </div>
        </fieldset>
    </form>
</body>
</html>

结构中每个input都有一个id,这样显得很方便我们控制,但我们都是要实现同样的效果,我们并不能通过说分别获取每一个id,然后给每一个该id的节点添加一个onfocus事件,这样太麻烦了。我们先看他提供的JQ代码是怎么解决的:


$(function(){
    $(":input").focus(function(){
        $(this).addClass("focus");
        if($(this).val() == this.defaultValue){
            $(this).val("");
        }
    }).blur(function(){
        $(this).removeClass("focus");
        if($(this).val() == ""){
            $(this).val(this.defaultValue);
        }
    })
})

可以看到,用JQ非常简单的就可以获取到所有input节点,并且,在JQ的实现中,textarea也包括在input里,因为他们都为文本框,JQ将他们都实现在:input中。

但是,JS并没有这样的方法,即使获取所有的input,但还有个textarea,难道要分开获取再分开写事件吗?

在这里,我个人是这样处理的,获取所有form下的elements元素,在此结构中,除了label不包含在form.elements下外,其他都属于form.elements,那么,可以在遍历form.elements,再判断form.elements[i]!="FIELDSET",将满足条件的存进一个数组,这个数组,就是我们所要处理的所有节点了。就可以通过遍历这个数组,绑定onfocus事件了。具体代码如下:


window.onload = function(){
    var reg = document.getElementById("regForm");   //获取表单form
    var inputs = [];                 //定义一个数组存放所有文本框
    for(var i = 0; i < reg.elements.length; i++){
        if(reg.elements[i].tagName != "FIELDSET"){       //查找文本框并存进数组
            inputs.push(reg.elements[i]);
        }
    }
    for(var i = 0; i < inputs.length; i++){       //给每一个文本框添加事件
        inputs[i].onfocus = function(){ 
            addClass("focus",this);
            if(this.value == this.defaultValue){
                this.value = "";
            }
        }
        inputs[i].onblur = function(){
            removeClass("focus",this);
            if(this.value == ""){
                this.value = this.defaultValue;
            }
        }
    }
}

function addClass(className,node){     //增加样式函数
    return node.className += " " + className;
}

function removeClass(className,node){    去除样式函数
    eles = node.className.split(/\s+/);
    for(var i = 0,l = eles.length; i < l; i++){
        if(eles[i] == className){
            eles.splice(i,1);
        }
    }
    node.className = eles.join(" ");
    return node;
}