Internet Explorer的事件模型
除了上节所介绍的事件模型外,不同浏览器还有自身所独有的事件机制,例如,Internet Explorer就包含了不少独有的事件特性,这些事件特性包括Internet Explorer自己的事件绑定机制,以及独有的事件传播机制等。
使用script for绑定
Internet Explorer还支持两种自己独有的事件绑定方法。这两种方法都不需要在HTML元素中增加额外的属性,下面依次介绍Internet Explorer中的事件绑定方法。
在Internet Explorer 4.0以及更新的版本中,Microsoft扩展了<script.../>
元素,可以将它包含的脚本语句和某个元素的某个事件类型进行绑定,完成绑定的两个属性是for和event。
for属性的值必须是HTML文档中某个元素的id属性值,该属性值唯一地标识了该HTML元素。event属性值是该元素所支持的事件名称,如onmouseover、onclick等。一旦为该script标签指定了这两个属性,就表明该标签内的所有脚本绑定了该元素的对应事件。在这种绑定机制下,事件处理的脚本语句并不在函数中,而是在<script.../>
元素内。
注意
值得注意的是,这种绑定方式仅支持Internet Explorer 4.0以及更新的版本,其他浏览器则没有实现这个特殊的<script.../>
元素。因此应该尽量避免使用这种绑定方式,如果客户端的浏览器不是Internet Explorer 4.0或更新的版本,将不可避免地引起脚本错误。
使用attachEvent方法执行绑定
在W3C指定标准的事件模型之前,attachEvent()方法已经被实现了,并可被用于Internet Explorer 5.0以及更新的版本,该方法可以作用于浏览器中的每个HTML元素。
attachEvent()方法的语法格式如下:
domObject.attachEvent("eventName",funtionReference);
与attachEvent()方法对应的是detachEvent()方法,该方法用于删除一个事件处理器,其语法格式如下:
domObject.detachEvent("eventName",funtionReference);
例子
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title> 使用attachEvent绑定事件处理函数 </title>
</head>
<body>
<input type="button" id="bn1" name="bn1" value="单击我" />
<script type="text/javascript">
var test = function()
{
alert("单击按钮");
}
var haha = function()
{
alert("haha函数也被触发");
}
// 使用attachEvent绑定事件处理函数
document.getElementById("bn1")
.attachEvent("onclick" , test);
// 使用attachEvent绑定事件处理函数
document.getElementById("bn1")
.attachEvent("onclick" , haha);
</script>
</body>
</html>
注意
这种事件绑定机制只是Internet Explorer所提出的事件绑定机制,并不是W3C制定的行业规范,其他浏览器暂不支持这种事件绑定机制,目前还有Opera支持这种事件绑定机制。
访问事件对象
Internet Explorer中的事件对象是一个隐式可用的全局对象:event,当一个事件在浏览器中发生时,浏览器创建一个隐式可用的事件对象,JavaScript脚本通过event就可访问该对象。
Internet Explorer中的事件对象有如下常用的属性。
➢ type:返回发生的事件类型,例如"click"等。
➢ srcElement:返回发生事件的HTML元素。
➢ clientX:返回发生鼠标事件在页面中的X坐标。
➢ clientY:返回发生鼠标事件在页面中的Y坐标。
➢ offsetX:返回发生鼠标事件位置相对于事件源的X坐标。
➢ offsetY:返回发生鼠标事件位置相对于事件源的Y坐标。
➢ button:对于鼠标事件有效,返回发生鼠标事件时所用的鼠标键。
➢ keyCode:对于键盘事件有效,返回发生键盘事件时所用的键盘键。
➢ altKey:返回boolean值,用以确定事件发生时是否按下了Alt组合键。
➢ ctrlKey:返回boolean值,用以确定事件发生时是否按下了Ctrl组合键。
➢ shiftKey:返回boolean值,用以确定事件发生时是否按下了Shift组合键。
➢ cancelBubble:阻止事件冒泡。关于事件传播,请看15.3.3节内容。
➢ returnValue:返回事件处理函数的返回值。在整个事件传播链中,事件处理函数可以改变该值,当该值被设为false时,该事件的默认行为被取消。
➢ fromElement:对mouseover和mouseout两个事件有效,用于返回鼠标移出的HTML元素。
➢ toElement:对mouseover和mouseout两个事件有效,用于返回鼠标移入的HTML元素。
例子
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title> JavaScript树 </title>
<style type="text/css">
/* 控制根节点的CSS样式定义 */
.outline {
font-size: 9pt;
margin-left: 15pt;
text-indent: -28pt;
cursor: hand;
text-decoration: none
}
/* 控制第一级子节点的CSS样式定义 */
.outline1 {
font-size: 9pt;
margin-left: 24pt;
text-indent: -36pt;
cursor: hand;
text-decoration: none
}
/* 控制第二级子节点的CSS样式定义 */
.outline11 {
font-size: 9pt;
margin-left: 38pt;
text-indent: -50pt;
cursor: hand;
text-decoration: none
}
/* 控制根节点下叶子节点的CSS样式定义 */
.passage0 {
font-size: 9pt;
margin-left: 15pt;
text-indent: -28pt;
text-decoration: none
}
/* 控制第一级节点下叶子节点的CSS样式定义 */
.passage1 {
font-size: 9pt;
margin-left: 24pt;
text-indent: -36pt;
text-decoration: none
}
/* 控制第二级节点下叶子节点的CSS样式定义 */
.passage11 {
font-size: 9pt;
margin-left: 38pt;
text-indent: -50pt;
text-decoration: none
}
</style>
<script type="text/javascript" src="tree.js">
</script>
</head>
<body>
<div id="root" class="outline">
<img id="rootImage" class="outline" alt="rootImage"
src="image/plus.gif" />我的电脑</div>
<div id="rootDetails" style="display:none">
<div id="child1" class="outline1">
<img id="child1Image" class="outline1" alt="child1Image"
src="image/plus.gif" />本地磁盘 C:</div>
<div id="child1Details" style="display: none">
<div class="passage11">
<img class="passage11" src="image/passage.gif" />文件一</div>
<div class="passage11">
<img class="passage11" src="image/passage.gif" />文件二</div>
</div>
<div id="child2" class="outline1">
<img id="child2Image" class="outline1" alt="child2Image"
src="image/plus.gif" />本地磁盘 D:</div>
<div id="child2Details" style="display: none">
<div class="passage11">
<img class="passage11" src="image/passage.gif"/>文件三</div>
<div class="passage11">
<img class="passage11" src="image/passage.gif"/>文件四</div>
</div>
<div id="child3" class="outline1">
<img id="child3Image" class="outline1" alt="child3Image"
src="image/plus.gif" />本地磁盘 E:</div>
<div id="child3Details" style="display: none">
<div class="passage11">
<img class="passage11" src="image/passage.gif" />文件五</div>
<div class="passage11">
<img class="passage11" src="image/passage.gif" />文件六</div>
</div>
<div class="passage1">
<img class="passage1" src="image/passage.gif" />文件七</div>
</div>
</body>
</html>
tree.js
var clickHandler = function()
{
// 定义需要操作的HTML元素id
var targetId;
// 定义需要被操作的HTML元素
var targetElement;
// 定义触发事件的事件源(其中event是隐式可用的全局对象)
var srcElement = event.srcElement;
// 根据其className属性值判断它不是叶子节点,即该节点可以展开
if(srcElement.className.substr(0,7) == "outline")
{
// 如果事件源是树节点前的图片
if(srcElement.id.indexOf("Image") > 0)
{
// 获取该节点对应<div.../>元素的id
targetId = srcElement.id.substring(0
, srcElement.id.length - 5) + "Details";
}
// 如果事件源是树节点所在的<div.../>元素
else
{
// 获取该节点对应<div.../>元素的id
targetId = srcElement.id + "Details";
}
// 找到对应的<div.../>元素
targetElement = document.getElementById(targetId);
// 如果targetElement对象存在
if(targetElement)
{
// 如果该<div.../>元素处于“隐藏”状态
if (targetElement.style.display == "none")
{
// 显示该<div.../>元素
targetElement.style.display = "";
}
else
{
// 否则,隐藏该<div.../>元素
targetElement.style.display = "none";
}
}
// 如果事件源是树节点前的图片
if (srcElement.id.indexOf("Image") > 0)
{
// 获取该节点前的<img.../>元素的id
targetId = srcElement.id;
}
// 如果事件源是树节点所在的<div.../>元素
else
{
// 获取该节点前的<img.../>元素的id
targetId = srcElement.id + "Image";
}
// 找到对应的<img.../>元素
targetElement = document.getElementById(targetId);
// 如果该<img.../>元素中显示的图片是“加号”图片
if (targetElement.src.indexOf("plus") >= 0)
{
// 将<img.../>的“加号”图片换为“减号”图片
targetElement.src = "image/minus.gif";
}
else
{
// 否则,将<img.../>的“减号”图片换为“加号”图片
targetElement.src = "image/plus.gif";
}
}
}
//为页面文档的onclick事件绑定事件处理函数
document.onclick = clickHandler;
前面介绍的是将事件处理器绑定到DOM对象时获取事件的方式,如果绑定到HTML元素属性,则还有另一种绑定方式:由于绑定到HTML元素属性时可以传入参数,因此我们可以将event对象作为参数传入。
例子
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title> Internet Explorer事件绑定 </title>
</head>
<body>
<!-- 绑定事件处理器时,将event作为参数传入 -->
<button onclick="clickHandler(event);">按钮</button>
<script type="text/javascript">
var clickHandler = function(evt)
{
// evt参数由系统传入,evt可访问事件对象
alert(evt.srcElement.innerHTML);
}
</script>
</body>
</html>
注:本博客内容节选自李刚编著的疯狂HTML 5/CSS 3/JavaScript讲义 ,详细内容请参阅书籍。