onload = *而不是onload()=*
在有些浏览器,脚本是和正文分开加载的,你这个document.getElementsByTagName("input");返回有可能没有值,
首先写一个简单的ready函数
// 只接受函数作为参数,每调用一次,存一个函数,当页面载完,一次自动执行
// ready(yourfunction)
var ready=(function () {
var isReady = false,
funList = [];
function r(fn) {
typeof fn !== "function" || (isReady ? fn() : funList.push(fn))
}
function readyCall() {
isReady = true;
while (funList.length) {
funList.shift()()
}
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function () {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
readyCall()
}, false)
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function () {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", arguments.callee);
readyCall()
}
})
}
return r
}
() )
再写一个绑定事件的函数
/**
* bind(target, event name, event function)
* bind(控件,事件名称(如"click"不带on),事件函数)
* 注意,事件函数,就算在ie,也会强推一个event作为第一个参数
* 为了兼容旧版本浏览器,preventDefault preventDefault 简单的写了些,不够完
* 还望海涵
*/
var bind = function (el, name, fn) {
if (el.addEventListener) {
el.addEventListener(name, fn);
} else {
name = "on" + name;
if (el.attachEvent) {
el.attachEvent(name, function () {
var args = Array.prototype.slice.call(arguments), ret = true;
if (window.event) {
args.unshift(window.event);
if (!event.preventDefault)
event.preventDefault = function () {
ret = false;
};
if (!event.stopPropagation)
event.stopPropagation = function () {
event.cancelBubble = true;
};
}
fn.apply(this, args);
return ret;
});
} else {
var old = el[name], noFunc = typeof old !== "function", noList = noFunc || !old.list, call;
if (noList) {
call = el[name] = function (event) {
var list = call.list, l = list.length,
args = Array.prototype.slice.call(arguments), ie = !!window.event,
ret = true, run = true;
if (!event.preventDefault)
event.preventDefault = function () {
ret = false;
};
if (!event.stopPropagation)
event.stopPropagation = function () {
run = false;
};
if (ie)args.unshift(event);
while (l-- && run)
list[i].apply(this, args);
return ret;
};
call.list = [];
if (!noFunc)call.list.push(old);
}
call.list.push(fn);
}
}
};
时间关系,没写解绑函数
再来一个寻找控件的函数
/**
* trans("#id") trans(".class") trans("$name") trans("tagName")
*/
function trans(el){
var c;
c = el.charAt(0);
c = c.match(/^[#\.\$]/)?c:"";
return typeof el==="object" &&
Object.prototype.toString.call(el).match(/\[object HTML.*Element\]/)?el
: typeof el==="string" &&
(el=(document[
["getElementById","getElementsByClassName","getElementsByName","getElementsByTagName"]
[{"#":0,".":1,"$":2,"":3}[c]]])(el.substring(c?1:0)),c?[el]:el.length)?el:null;
}
然后再轻松的绑定事件
ready(function(){
var fruit = trans("input");
//初始化
for(var i=0;i<fruit.length-4;i=i+2)
fruit[i+1].disabled="disabled";
//添加事件
for(var i=0;i<fruit.length-4;i=i+2)
bind(fruit[i],"click",(function(fruit,value){
return function(event){
if(fruit.id === value)fruit.removeAttribute("disabled");
};
}(fruit[i],fruit[i].value)));//注意,这里直接把fruit[i].value,和fruit[i]传给事件闭包,就不容易和其他变量混淆了。
});
追问
追答fruit[i].onclick=(function(x){
return function(){ alreadyChoose(x);}
}(x));
//才能保证每个控件的x不一样,否则他们的x其实是一样的。
所谓闭包,刚开始,可以简单理解为保护的局部变量。我这个方法就是闭包的一种。javascript的闭包比较绕人,我也是最近才弄清楚。