好!欢迎访问迷津渡口 现在时间是: 天气 °C ~ °C

迷津渡口

越感到迷惑 越接近真理

javascript事件触发多个函数

javascript的核心之一就是处理事件,一般时候一个事件触发一个没参数的函数,如丝般顺滑,没毛病!

但是,在实际的使用中,一个事件经常需要触发多个函数:

var example=document.getElementById("example");
example.onmouseover=fontResize;
example.onmouseover=colorChange;
example.onmouseout=resetIt;

此时我们会发现onmouseover事件发生的时候只能触发colorChange函数运行,fontResize则毫无动静,另外这种方法无法为函数传参数。

事实上这是DOM Level 0对事件的规定决定的,事件作为对象的属性,在被赋值时前面的值会被覆盖,因此在实际触发时只有最后一个值被赋给了事件属性,这就是所谓的来得早不如来得巧啦^_^


在DOM Level 0下,大家普遍采用两种方法解决这个bug:

一、html属性赋值

不推荐,但是现在依然常用。

什么意思,就是直接在html内容里面设置事件和回调函数:

<a id="example" href="http://www.qingzz.cn/" onmouseover="fontResize("bigSize");colorChange("redColor");">迷津渡口</a>

这样调用非常方便,可以方便地添加参数,也可以调用多个函数,所有的bug貌似都消失了。

但是大多数大神都不推荐使用这种方法,原因是这种方法违反了js,css,html分开的原则。

有时我们小站怎么方便怎么来嘛,管你呢^_^


二、采用函数字面量

DOM Level 0下最受推崇的方法。


首先介绍一下何为函数字面量。

大家都知道,函数其实是可以作为右值赋给变量的:

function example () {
    alert("普通函数的函数名为函数字面量。");
}
ex=example;//赋值

调用的时候使用ex()和example()是等价的,记住作为函数字面量的是函数名,不需要括号和参数。


另外一种函数字面量是没有名字的函数:

ex=function() {alert("无名函数也可以作为函数字面量。");};

调用时可以使用ex();


了解了函数字面量,有想法了没?

var example=document.getElementById("example");
example.onmouseover=function(){fontResize("bigSize");colorChange("redColor");};
example.onmouseout=resetIt;

发现了吧,这种方法可以说相对完美,添加参数和多个回调函数的问题都解决了。

但是,如果函数里面包含对象this,则函数就无法很好的运行了。

function fontResize(classSet) {
    this.className+=classSet;
}
function colorChange(classSet) {
    this.className+=classSet;
}

平时没参数的单个函数使用this可以很方便获取对象,实际上还是有默认传递一个对象参数。

多个函数时,需要显式传递一个对象参数:

function fontResize(obj,classSet) {
    obj.className+=classSet;
}
function colorChange(obj,classSet) {
    obj.className+=classSet;
}

调用函数时,传递this对象:

var example=document.getElementById("example");
example.onmouseover=function(){fontResize(this,"bigSize");colorChange(this,"redColor");};
example.onmouseout=resetIt;

函数方法addEventListener和attachEvent

其实在DOM Level 2里定义了专门用于为事件添加多个函数的方法:

obj.addEventListener(eventName,functionName,false);

第一个参数是事件名但是前面没有"on",例如"mouseover";

第二个参数是函数字面量,即函数名或者无名函数(带参数的只能通过这种);

第三个参数表示使用事件浮升,具体的可以不管啦^_^想知道的自己百度~

没参数的直接使用函数名:

var example=document.getElementById("example");
example.addEventListener("mouseover",fontResize,false);
example.addEventListener("mouseover",colorChange,false);
example.onmouseout=resetIt;

有参数的使用无名函数:

var example=document.getElementById("example");
example.addEventListener("mouseover",function(){fontResize("bigSize");},false);
example.addEventListener("mouseover",function(){colorChange("redColor");},false);
example.onmouseout=resetIt;

执行顺序可以说没特别的关系,也可以说是从前到后执行,但不用特别关注。


DOM Level 2出来之前,IE大哥已经自己搞了一套,那就是attachEvent,现在依旧沿用。

obj.attachEvent(eventName,functionName)

第一个参数是事件名,包含"on",即和原来一样,仍旧是例如"onmouseover"一类的。

第二个参数是函数字面量,即函数名或者无名函数(带参数的只能通过这种)。

没有第三个参数,因为默认为事件浮升。

没参数的直接使用函数名:

var example=document.getElementById("example");
example.attachEvent("onmouseover",fontResize);
example.attachEvent("onmouseover",colorChange);
example.onmouseout=resetIt;

有参数的使用无名函数:

var example=document.getElementById("example");
example.attachEvent("onmouseover",function(){fontResize("bigSize");});
example.attachEvent("onmouseover",function(){colorChange("redColor");});
example.onmouseout=resetIt;

因此为了保证兼容性,需要这么做:

没参数的直接使用函数名:

var example=document.getElementById("example");
if (document.addEventListener) {
    example.addEventListener("mouseover",fontResize,false);
    example.addEventListener("mouseover",colorChange,false);
} else if (document.attachEvent) {
    example.attachEvent("onmouseover",fontResize);
    example.attachEvent("onmouseover",colorChange);
}
example.onmouseout=resetIt;

有参数的使用无名函数:

var example=document.getElementById("example");
if (document.addEventListener) {
    example.attachEvent("onmouseover",function(){fontResize("bigSize");});
    example.attachEvent("onmouseover",function(){colorChange("redColor");});
} else if (document.attachEvent) {
    example.attachEvent("onmouseover",function(){fontResize("bigSize");});
    example.attachEvent("onmouseover",function(){colorChange("redColor");});
}
example.onmouseout=resetIt;


分享工具函数addEventHandler和getActivatedObject

function addEventHandler(obj,eventName,handler) {
  if (document.attachEvent) {
    obj.attachEvent("on"+eventName,handler);
  } else if (document.addEventListener) {
    obj.addEventListener(eventName,handler,false);
  }
}

function getActivatedObject(e) {
  var obj;

  if (!e) {
    // early version of IE
    obj=window.event.srcElement;
  } else if (e.srcElement) {
    // IE 7 or later
    obj=e.srcElement;
  } else {
    // DOM Level 2 browser
    obj=e.target;
  }

  return obj;
}

使用方法:

在事件处理函数定义里无法使用this,而需要显式传递一个event参数,这个参数放在参数表的最后,事件处理函数会自动传递,不需要显式传递:

没其他参数的使用方法:

函数定义:

function fontResize(e) {
    var me=getActivatedObject(e);
    me.className+="bigSize";
}
function colorChange(e) {
    var me=getActivatedObject(e);
    me.className+="redColor";
}

无参数事件处理函数使用:

var example=document.getElementById("example");
addEventHandler(example,"mouseover",fontResize);
addEventHandler(example,"mouseover",colorChange);
example.onmouseout=resetIt;

多参数的定义方法:

function fontResize(classSet,e) {
    var me=getActivatedObject(e);
    me.className+=classSet;
}
function colorChange(classSet,e) {
    var me=getActivatedObject(e);
    me.className+=classSet;
}

多参数事件处理函数使用:

var example=document.getElementById("example");
addEventHandler(example,"mouseover",function(){fontResize("bigSize");});
addEventHandler(example,"mouseover",function(){colorChange("redColor");});
example.onmouseout=resetIt;


实际使用哪一种方法大家自己斟酌吧,推荐是最后一种方法啦,兼容性好。

本文写得太累了,拒绝转载,需要转载请联系站长^_^

点赞0
   支持一下
挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
 点赞
 签到
 表情
 图片
 代码
提交评论

清空信息
关闭评论
顶部留言底部
 00:00/00:00
我想和你虚度时光 - 花房姑娘(9)
  1. 我想和你虚度时光
  2. 花房姑娘
  3. 恋恋风尘
  4. 我喜爱一切不彻底的事物
  5. 我的心里是满的
  6. Long Way
  7. 给少年的歌
  8. 晴日共剪窗
  9. 天上的月你的脸