先给个例子。
访问事件对象
<body>
<button onclick="sayHi()">sayHi</button>
<button class="btn">bless</button>
<script>
function sayHi(){
console.log(window.event === event);
console.log(event);
console.log("hello");
}
var btn = document.querySelector(".btn");
btn.onclick = function(e){
console.log(e);
console.log("have a nice day");
}
</script>
</body>
<button onclick="sayHi()">sayHi</button>
,事件对象event
在window
上,因此 通过window.event
访问。
btn.onclick = function(e){}
,事件处理函数的第一个参数是事件对象。当然,也可以通过因此 通过window.event
访问事件对象。
想起 跨浏览器的事件处理程序 写法。瞧,不论onclick
在html里还是js里,getEvent
都能够返回 事件对象。
<body>
<button class="btn">bless</button>
<script>
var btn = document.querySelector(".btn");
var EventUtil = {
addHandler:function(elm,type,handler){
if(elm.addEventListener){
elm.addEventListener(type,handler,false);
}else
if(elm.attachEvent){
elm.attachEvent("on"+type,handler);
}else{
elm["on"+type] = handler;
}
},
getEvent:function(event){
return event||window.event;
}
}
EventUtil.addHandler(btn,"click",function(e){
var event = EventUtil.getEvent(e);
console.log(event);
console.log("have a nice day");
})
</script>
</body>
向事件处理程序传参
匿名函数 赋给 onclick
事件处理程序是一个匿名函数,它的 第一个参数 是 事件对象,只有这一个参数。
<body>
<button >sayHi</button>
<script>
var b = document.querySelector("button");
b.onclick = function(e){
console.log(e.type);
console.log("hello world");
}
</script>
</body>
已声明函数 赋给 onclick
事件处理程序 是 一个 已声明函数 doSomething
,它的第一个参数 是 事件对象,只有这一个参数。
<body>
<button >sayHi</button>
<script>
var b = document.querySelector("button");
function doSomething(e){
console.log(e.type);
console.log("hello world");
}
b.onclick = doSomething;
</body>
不论是将 匿名函数 还是 已声明函数 赋给 onclick
, 事件处理程序是一个函数,且只有一个参数,那就是 事件对象。
如果想向事件处理程序中传入其他参数,最简单直接的方式就是在 事件处理程序 中 通过调用其他函数,从而传入额外参数。就像这样。
<body>
<button >sayHi</button>
<script>
function doSomething(message,e){
console.log(`${e.type} occured,and the message is ${message}`)
}
var button = document.querySelector("button");
button.onclick = function(e){
doSomething("hello world",e);
}
</script>
</body>
我们来研究一个稍复杂点儿的,和this
指向有关。
向 事件处理程序 传入额外参数 有三种方式。
- 第一种,就像刚刚那样,在 事件处理程序 中 直接调用
TODO.doSomething
方法,并传入参数name:Nicholas
和 事件对象e
<body>
<button>click me </button>
<script>
var TODO = {
message:"hello world",
doSomething:function(name,e){
console.log(`${e.type} occured,and ${name} send a message:${this.message}`);
}
}
var button = document.querySelector("button");
button.onclick = function(e){
TODO.doSomething("Nicholas",e);
}
</script>
- 第二种,使用
Function.prototype.bind
<body>
<button>click me </button>
<script>
var TODO = {
message:"hello world",
doSomething:function(name,e){
console.log(`${e.type} occured,and ${name} send a message:${this.message}`);
}
}
var button = document.querySelector("button");
button.onclick = TODO.doSomething.bind(TODO,"Nicholas")
</script>
</body>
- 第三种,那就是自定义
bind
,本质上和Function.prototype.bind
是一样的
<body>
<button>click me </button>
<script>
var TODO = {
message:"hello world",
doSomething:function(name,e){
console.log(`${e.type} occured,and ${name} send a message:${this.message}`);
}
}
function bind(fn,context){
var args = Array.prototype.slice.call(arguments,2);
return function (){
var finalArgs = args.concat(Array.prototype.slice.call(arguments));
fn.apply(context,finalArgs);
// fn.call(context,...finalArgs);
}
}
var button = document.querySelector("button");
button.onclick = bind(TODO.doSomething,TODO,"Nicholas");
</script>
</body>