之前看js时有个题目,要求能够弹出对话框提示当前选中的是第几个单选框。
原题目比较简单,有submit,然后又调用。
<form name="form1" onsubmit="return foo();">
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="submit"/>
</form>
后突发奇想,如果没有onsubmit,题目改为如下,怎么解答呢?前提是不可以在html中修改任何代码(自己给自己出难题可能是所有研究代码人的乐趣了,呵呵。)
<form name="form1">
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
<input type="radio" name="radioGroup"/>
</form>
我第一个想到的代码是(注意这个是错的哦!):
var rg_arr = document.getElementsByName("radioGroup");
for(i=0;i<rg_arr.length;i++){
rg_arr[i].onclick = function(){
alert(i)
}
}
写完还暗自得意,结果一测试傻眼了,点任何单选按钮都弹出"6"。忽然想起js的闭包和之前看到的题目,做了如下改动(这个才是对的):
for(i=0;i<rg_arr.length;i++){
rg_arr[i].onclick = abc(i);
}
function abc(x){
return function(){
alert(x);
}
}
这次测试才得到正确结果,点击之后依次出现0,1,2,3,4,5,是利用闭包来影响变量的作用域。
而且此种方式兼容IE\FF,
再改动一下,如果题目变为:要求能够弹出对话框提示当前选中的单选框的值。
<form name="form1">
<input type="radio" name="radioGroup" value="111"/>
<input type="radio" name="radioGroup" value="222"/>
<input type="radio" name="radioGroup" value="333"/>
<input type="radio" name="radioGroup" value="444"/>
<input type="radio" name="radioGroup" value="555"/>
<input type="radio" name="radioGroup" value="666"/>
</form>
使用之前的方法,得到索引号,然后调出该索引对象的value也可以,但是我们需要更简便的方法,注意这个和索引的区别。
for(i=0;i<rg_arr.length;i++){
rg_arr[i].onclick = function abc(eve){ //保证兼容性,要传递点击的对象进去
ev = eve||window.event; //FF不认识window.event
tag = ev["target"]||ev["srcElement"]; //FF用前者,IE用后者
alert(tag.value) //弹出所选对象的value值
};
}
究其所以,开始时候的程序传递参数i,而i因为循环和不停改变,而此时程序中传递参数eve是onclick的对象,不因变量i的变化而变化,因此这里可以不使用闭包,通过调用对象的标签然后找到其value值即可