您的位置:首页 > Web前端 > JavaScript

js的事件

2016-12-14 21:39 190 查看

事件入门

什么是事件

事件是由用户和浏览器进行交互的操作

三种事件模型内联模型

内联事件模型

作为html标签的一个属性存在的,但是这种模型已经不适合在大的项目中使用。onclick

脚本模型

但是注意的是:如果这段脚本是对整个DOM进行操作的话,必须是在DOM加载完才执行这个脚本,让事件处理函数(onclick)执行一个函数的时候,通过赋值的方式,直接将函数名赋值给事件处理函数即可,而不是为这个事件处理函数赋值为函数() 如果有括号的话会自己调用,而不是等待事件来触发

DOM2级模型

事件处理函数

onclick等事件

onkeydown 事件 按下键盘上的任意的按钮都可以输出111

onkeydown=function(){
console.log(111);
}


onkeypress 事件 按下键盘上的字母键或者是数字键才可以触发这个事件,按下shift ctrl键都没有用

onkeypress=function(){
console.log(111);
}


onkeyup 事件在按下键盘并释放键盘的时候才会触发这个事件

onkeyup=function(){
console.log(111);
}


onunload 事件 在页面真个卸载的时候,才触发 比如说刷新的时候

onselect 事件 选择文本输入框的内容 释放的时候会触发这个事件

cc.onselect=function(){
console.log(11);
}


onchange 事件 文本框内改变内容并且失去焦点的时候触发

form上边的事件 这些表单必须在一个form里边

submit没有form是提交不了的,而且不是在input上边触发的,而是在form上边触发的

onresize事件 window 的事件 改变窗口的大小会触发的事件

onscroll事件 window 的事件 滚动窗体的时候会触发的事件

事件对象

事件处理的三个部分

1、DOM 2、事件处理函数 3、事件处理方法

事件对象

当触发一个事件的时候就会产生一个事件对象 浏览器通过函数把这个对象作为参数传递过来,event,所以这个对象会存在非常多的兼容性(就连得到这个对象的方式)

window.onload=function(){
var box=document.getElementById("box");
box.onclick=function(){
console.log(arguments.length)    //点击的时候会传递一个事件对象  所以这里会输出1
}
}


所以下面的代码也可以

var box=document.getElementById("box");
box.onclick=function(e){
console.log(e)    //得到的就是事件对象
}


值得注意的是,IE中都不支持这种方式来得到事件对象,上面的方式是W3C获取事件对象的方式,在IE下可以通过window的属性直接来获取

下面的代码实现了获取事件对象的兼容

box.onclick=function(e){
var event=window.event||e;
alert(event)    //得到的就是事件对象
}


鼠标事件对象跨浏览器来获得用户按下是左键?中键?右键?

window.onload=function() {
var box = document.getElementById("box");
document.onmouseup=function(e){
var event=e||window.event;
alert(getButton(e));
}
}
function getButton(event){
if(event){
return event.button;
}
else if(window.event){
switch(window.event.button){
case 1: return 0;
case 4: return 1;
case 2: return 2;
}
}
}


跨浏览器获得鼠标点击位置在视窗的位置(不管你是放大了浏览器还是有了滚动条,都是看的是鼠标的点击的位置离视窗的位置),而且这个程序还可以输出有滚动条的时候,滚动条的离顶部的位置

document.onmouseup=function(e){
var event=window.event||e;
alert(document.documentElement.scrollTop||document.body.scrollTop+"px"+event.clientX+"px"+ event.clientY+"px");
}


值得注意的是:获得滚动条离最顶部的距离的时候的兼容的情况

下面这个程序是获得了鼠标点击的位置离屏幕的距离

document.onmouseup=function(e){
var event=window.event||e;
alert(event.screenX+"px"+"   "+event.screenY+"px");
}


注意:只能为alert传递一个参数

下面的函数判断是否按下修改键(shift、ctrl、alt)

window.onload=function() {
document.onclick=function(e){
alert(getKey(e));
}
}
function getKey(evt) {
var e = evt || window.event;
var keys = [];
if (e.shiftKey) keys.push('shift'); //给数组添加元素
if (e.ctrlKey) keys.push('ctrl');
if (e.altKey) keys.push('alt');
return keys;
}


注意:上面的功能实现的是在按住shift键、ctrl键、alt键的情况下,点击屏幕会输出按下的修改键

键盘事件

keydown 按下键盘

keyup 键盘起来的时候

keypress 按下字母键盘的时候

按下键盘并返回键码keycode (键码可以返回任意键的编码,而且字母不区分大小写)

document.onkeydown=function(e){
var event=e||window.event;
alert(event.keyCode)
}


但是使用了onkeypress来返回键码,在火狐浏览器中不支持(按下键盘的时候返回的是0),在谷歌浏览器和IE中虽然支持但是区分大小写

document.onkeypress=function(e){
var event=e||window.event;
alert(event.keyCode)
}


火狐和谷歌浏览器都支持的事件对象都支持charCode,和keyPress搭配来得到字符编码,注意IE的事件对象没有这个属性

document.onkeypress=function(e){
var event=e||window.event;
alert(event.charCode)
}


跨浏览器获得按下键盘的编码

window.onload=function() {
document.onkeypress=function(e){
alert(getCharCode(e))
}
}
function getCharCode(e){
var event=e||window.event;
if(typeof event.charCode=="number"){
return event.charCode;
}
else{
return event.keyCode;
}
}


w3c和IE的事件

得到事件的目标

,(鼠标点在哪里,就可以得到哪里的dom对象)

跨浏览器获得事件的目标

window.onload=function() {
document.onclick=function(e){
alert(getTarget(e).tagName);
}
}
function getTarget(e){
var event=e||window.event;
if(event.target){
return event.target;
}
else{
return event.srcElement
}
}


事件流

事件流有两种模式:冒泡和捕获



html代码

<div style="background: red;width: 100px;height: 100px" id="box">
<button > 点击</button>
</div>


js代码

window.onload=function() {
document.onclick=function(){
alert("documnet");
}
document.documentElement.onclick=function(){
alert("html");
}
document.body.onclick=function(){
alert("body");
}
document.getElementById("box").onclick=function(){
alert("box");
}
document.getElementsByTagName("button")[0].onclick=function(){
alert("input");
}

}


在任何的浏览器点击按钮的时候依次会输出 input box body html document

取消冒泡模式

document.getElementsByTagName("button")[0].onclick=function(e){
alert("input");
e.stopPropagation();  //IE不支持
}


只是取消了点击按钮的冒泡

跨浏览器阻止事件冒泡

function stopBubble(e){
var event=e||window.event;
(typeof event.stopPropagation=="function")? event.stopPropagation(): event.cancelBubble=true;
}


事件绑定

传统事件绑定

如果一个页面有两个或者多个js脚本文件,导致会有多个window.onload这两个事件,这就会导致第一个window.onload会被覆盖,解决的方法:在使用window.onload的时候,首先要检测是否存在window.onload是否是一个函数

下面就是解决覆盖的问题

window.onload=function () {
alert("dd");
}
if(typeof window.onload=="function"){
var saved=null;
saved=window.onload;
}window.onload=function () {
if(saved)saved();
alert("cc");
}


事件切换器

<style>
.red{
background: red;
width:200px;
height: 200px;
}
.blue{
background: blue;
width:200px;
height: 200px;
}
</style>
<body>
<div id="test" class="blue"></div>
</body>


js代码

window.onload=function () {
var test=document.getElementById("test");
console.log(test)
test.onclick=toBlue;
}
function toRed(){
this.className='red';
this.onclick=toBlue;
}
function toBlue(){
this.className='blue';
this.onclick=toRed;
}


注意,通过匿名函数执行一个函数,那么这个函数里面的this就会代表window,但是匿名函数这个this中还是属于当前对象的

test.onclick=function(){
alert(this);   //div
toBlue();
};
function toBlue(){
alert(this);   //会弹出window
this.className='blue';
this.onclick=toRed;
}


所以下面的这个代码也实现了事件的切换

test.onclick=function(){
toBlue.call(this);
};
function toRed(){
this.className='red';
this.onclick=toBlue;
}
function toBlue(){
this.className='blue';
this.onclick=toRed;
}


所以传统事件的绑定有许多的缺点,所以我们要自定义函数来实现事件的绑定

有一点值得注意window.onload相当于window[“onload”]

//obj  相当于window
//type   相当于onload
//fn    相当于function
function addEvent(obj,type,fn){
removeEvent(obj,type);   //一道切的移除事件的函数
var saved=null;
if(typeof obj['on'+type]=='function'){
saved=obj['on'+type];
}
obj['on'+type]=function(){
if(saved){
saved();
}
//用它来做事件切换器   注意this
fn.call(this);
}
}
function removeEvent(obj,type){
if(typeof obj['on'+type]=='function') {
obj['on'+type]=null;
}
}


使用新的绑定事件的方式实现事件切换器

addEvent(window,'load',function () {
var test=document.getElementById("test");
addEvent(test,'click',toBlue)
})
function toRed(){
this.className='red';
addEvent(this,'click',toBlue);
}
function toBlue(){
this.className='blue';
addEvent(this,'click',toRed);
}


W3C事件绑定机制

DOM2级定义了两个事件的处理方法 添加事件 删除事件

也就是addEventListener()和removeEventListener()但是这两个方法只能在支持W3C的事件模型的浏览器上运行

传递的参数 对象.addEventListener('事件',事件处理函数,捕获(true)还是冒泡false)

window.addEventListener('load',function () {
alert(11);
},false)
window.addEventListener('load',function () {
alert(22);
},false)


1、DM2级事件模型的绑定事件解决了覆盖的问题(一次会弹出11 22)

window.addEventListener('load',init,false)
window.addEventListener('load',init,false)
window.addEventListener('load',init,false)
function init() {
alert(1);
}


2、相同的函数多次绑定到同一个函数的时候,会自动的屏蔽(会之弹出一次1,自动屏蔽)

window.addEventListener('load',function () {
var test=document.getElementById("test");
test.addEventListener('click',toBlue,false);
},false)
function toRed() {
this.className="red";
this.removeEventListener('click',toRed,false);   //必须要有这一步,否则没有办法进行事件的切换
this.addEventListener('click',toBlue,false);
}
function toBlue() {
this.className="blue";
this.removeEventListener('click',toBlue,false); //必须要有这一步,否则没有办法进行事件的切换
this.addEventListener('click',toRed,false);
}


3、可以传递this,实现事件的切换器,直接在toRed使用this

test.addEventListener('click',function () {
alert(11);
},false);
test.addEventListener('click',toBlue,false);


4、添加一个额外的方法,会不会被覆盖或者只执行了一次,实现了点击的时候既可以弹出11也可以变色

综上所述,W3C的addEventListener和removeEventListener完美的解决了事件的绑定,但是IE8及其以下的版本都不支持DOM2级的这个事件模型,而是采用了自己的事件。

冒泡和捕获(设置true和false)

test.addEventListener('click',function () {
alert("div");
},true);
document.addEventListener('click',function () {
alert("document")
},true);


设置为了捕获,点击div的时候,先弹出document再弹出div

IE事件处理函数

注意以下的测试必须在IE8及以下完成:

attachEvent(‘on+事件名称’,’事件处理函数’)

detachEvent(‘事件名称’,’事件处理函数’)

因为IE8以下中的事件

1、不支持捕获,

2、IE事件不能屏蔽重复的函数

3、IE中的this指向的是widow而不是DOM对象(不可以传递this)

4、传统的IE事件模型上,IE是无法接收到event对象,但是使用了attachEvent()却可以

但是也解决了

1、覆盖问题

window.attachEvent('onload',function () {
alert(1);
})
window.attachEvent('onload',function () {
alert(2);
})


但是会先弹出2 在弹出1

让IE和W3C兼容这个事件切换器

1、跨浏览器添加事件

function addEvent(obj,type,fn) {
if(obj.addEventListener){
obj.addEventListener(type,fn,false);
}else if(obj.attachEvent){
obj.attachEvent('on'+type,fn)
}
}


2、夸浏览器移除事件

function removeEvent(obj,type,fn) {
if(obj.removeEventListener){
obj.removeEventListener(type,fn);
}else if(obj.detachEvent){
obj.detachEvent('on'+type,fn)
}
}


3、跨浏览器获取目标对象

function getTarget(e) {
if(e.target){
return e.target;
}
else if(window.event.srcElement){
return window.event.srcElement
}
}


事件对象的其他补充

W3C的relatedTarget这个属性可以在mouseover和mouseout事件中获取从哪里移入和从哪里移出

<span id="pox">
<div id="box"></div>
</span>


js代码

addEvent(window,'load',function () {
var box=document.getElementById("box");
addEvent(box,'mouseover',function (evt) {
alert(evt.relatedTarget)  //得到移入box的最近的对象   会弹出span
})
})


跨浏览器阻止事件的默认行为

//跨浏览器阻止事件的默认行为
function predefault(evt) {
var event=evt||window.event;
if(event.preventDefault)
{
event.preventDefault();
}
else{
event.returnValue=false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: