《JavaScript精粹(修订版)》——1.8 让不同的脚本在同一页面中协同工作

1.8 让不同的脚本在同一页面中协同工作

如果几个脚本总是不能协同工作,那么很有可能是因为这些脚本试图对某给定元素的同一种事件处理赋予了不同的处理函数。因为每个元素对每个事件只有一个处理方法,所以同一个事件的处理会被不同的处理函数重复地替换。

方 法
通常应该怀疑的是window对象的load事件处理,因为在同一页面中,只有一个脚本能够使用这个事件;如果两个或者多个脚本尝试使用该事件,那么最后一个脚本会将前面脚本的处理函数覆盖掉。

可以在load事件处理函数中调用多个函数,如下:

window.onload = function()
{
  firstFunction();
  secondFunction();
}

不过,如果这样做,就必须受限于在load事件的处理函数中完成所有的任务。另一个好一点的解决方案是提供一个函数,可以增加对load事件的处理而不与其他已经添加的处理函数冲突。

使用下面的函数,可以添加任意数量的load事件的处理函数,而无需担心它们发生冲突:

文件:add-load-listener.js

function addLoadListener(fn)
{
  if (typeof window.addEventListener != 'undefined')
  {
    window.addEventListener('load', fn, false);
  }
  else if (typeof document.addEventListener != 'undefined')
  {
    document.addEventListener('load', fn, false);
else if (typeof window.attachEvent != 'undefined')
{
  window.attachEvent('onload', fn);
}
else
{
  var oldfn = window.onload;
  if (typeof window.onload != 'function')
  {
    window.onload = fn;
  }
  else
  {
    window.onload = function()
      {
        oldfn();
        fn();
      };
    }
  }
}

这样,就可以随心所欲地增加新的load事件处理函数了,如下:

addLoadListener(firstFunction);
addLoadListener(secondFunction);
addLoadListener(twentyThirdFunction);

讨 论
JavaScript包括了给事件增加或删除监听器的方法,看上去有点儿像普通的事件处理,但却允许多个监听器订阅同一个元素的同一个事件的消息。但是,在Internet Explorer中这种监听器的语法与在其他浏览器中的语法完全不同,IE使用一种独有的方式,而其他浏览器则完全按照W3C标准来实现。开发者经常处于这种折磨之中,在第13章将会讨论有关的细节。

W3C标准方法叫做addEventListener:

window.addEventListener('load', firstFunction, false);
IE的方法叫做attachEvent:

window.attachEvent('onload', firstFunction);
正如您所看到的,标准的创建方法是,直接使用事件的名字(没有on前缀),事件发生时需要调用的函数以及一个用于控制事件传递的参数放在事件名字的后面(第13章会有更详细的讨论)。IE的方法则使用事件处理者的名字(前面带有一个on前缀),需要调用的函数的名字放在其后。

在将代码组织到一起的时候,还需要测试一下试图调用的方法是否存在。可以用JavaScript的typeof操作符,它可以区分数据的不同类型(例如字符串、数字、布尔值、对象、数组、函数或者未定义类型)。一个不存在的方法会返回未定义类型。

if (typeof window.addEventListener != 'undefined')
{
  ┆支持window.addEventListener
}

还有一点稍稍复杂的地方:在Opera中,load事件可以激发来自文档对象的事件监听器,却不能激发来自窗口对象的监听器。不过如果只使用文档对象,这样的代码在老版本的Mozilla浏览器中(例如Netscape 6)又不能工作。为了处理这种问题,还必须测试一下window.addEventListener,然后是document.addEventListener,最后才是window.attachEvent。

最后,对于那些根本不支持这些方法的浏览器(例如Mac IE 5),备用的方案是使用老式的链式事件处理方式,这样在事件发生时事件处理函数仍能被调用。可以动态地创建一个新的事件处理函数,当事件发生时,先调用老的事件处理函数,再调用新的事件处理函数1。

文件:add-load-listener.js (excerpt)

var oldfn = window.onload;
if (typeof window.onload != 'function')
{
 window.onload = fn;
}
else
{
 window.onload = function()
 {
  oldfn();
  fn();
 };
}

如果您现在对这些代码怎样工作还不太理解,不用担心,后续章节还会讨论更多的细节。后面大家会了解到事件监听器不仅适用于load事件,也适用于任何事件驱动的脚本。

时间: 2024-08-13 20:21:52

《JavaScript精粹(修订版)》——1.8 让不同的脚本在同一页面中协同工作的相关文章

《JavaScript精粹(修订版)》——导读

**前言**对很多人来说,提起JavaScript,常常伴随着很多不愉快的记忆,例如讨厌的弹出式窗口.恼人的鼠标尾迹,还有令人沮丧的禁止鼠标右键的脚本.如果常常遇到这些脚本,就知道那是多么乏味和无聊.不过,JavaScript确实是一种成熟.专业的脚本语言,广泛地应用于现在的大多数网站,而且,它也几乎是所有基于Web的应用程序的关键性组件.别奇怪,我们确实是在谈论同一种技术. 当然,回顾过去,我认为很多人对JavaScript的感受还是比较准确的:JavaScript确实名声不太好,随着大量网站

《JavaScript精粹(修订版)》——1.10 脚本调试

1.10 脚本调试 调试是一个查错改错的过程.绝大多数浏览器拥有内建的报告错误的功能,还有一些外部的调试工具也值得关注. 1.10.1 理解浏览器内建的错误报告 Opera.Mozilla浏览器(例如FireFox)以及Internet Explorer都拥有很好的内建的错误报告功能,不过Opera和Mozilla的调试工具最为有用. (1)Opera. 通过菜单Tools→Advanced→JavaScript console可以打开JavaScript控制台.也可以把它设置为遇到错误的时候自

《JavaScript精粹(修订版)》——1.7 给页面添加脚本

1.7 给页面添加脚本 要想让脚本工作,首先需要在页面中将其载入.有两种技术可以做到这一点,而其中一种技术明显优于另一种. 方 法 第一种,也是最直接的方法,是把代码写入script元素中,正像前面看见过的那样: <script type="text/javascript"> function saySomething(message) { alert(message); } saySomething('Hello world!'); </script> 这种方

《JavaScript精粹(修订版)》——1.5 内容和行为的隔离(谨慎地编码)

1.5 内容和行为的隔离(谨慎地编码) 将内容从行为中分离,意味着按照网页的结构分离出不同的层次来.Jeffrey Zeldman曾经将Web开发形容为"三条腿的板凳"1,分别是内容(HTML).表示(CSS).行为(JavaScript),他不仅指出三者在功能上的不同,同时也表明他认为这三者应该被互相隔离开来. 好的隔离方式将使得网站更容易维护,也更容易被理解和使用,同时对于老的或者支持特性较少的浏览器也能够提供相应的访问方式. 方 法 以下是一种极端情况,正好与理想的行为和内容互相

javascript如何解析base64图片数据 并且将图片显示在网页中

问题描述 javascript如何解析base64图片数据 并且将图片显示在网页中 最好是有详细的javascript解析base64的源代码(本人初学者请见谅),显示这一块儿 怎么获取javascript解析好的图片 麻烦各位大神了 急!急!急! 解决方案 var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var base64DecodeChars =

网页页面中如何用Javascript调用Flash动画?

flash动画|javascript|网页|页面 问:网页页面中如何用Javascript调用Flash动画? 答: 在<HEADE>区加入  程序代码 <script src="js/flash.js" type="text/javascript"></script> 在调用FLASH处加入  程序代码 <script language="JavaScript" type="text/java

javascript在子页面中函数无法调试问题解决方法

 遇到在子页面中提交的时候会无法能够调试javascript代码的情况出现,下面有个不错的解决方法,希望对大家有所帮助 近期在做一个项目,会遇到在子页面中提交的时候会无法能够调试javascript代码的情况出现,有时候这种问题,我们无法正常在浏览器,看到我们子页面的javascript代码,所以只能够用原始的alert 或者 console.log(),当然,这也是一种解决方法,但是有时候,我们就想看一下程序到底是如何运行的,同时也可以看每个参数到底是什么值,所以意义还是比较大的.    我贴

JavaScript跨浏览器获取页面中相同class节点的方法

 这篇文章主要介绍了JavaScript跨浏览器获取页面中相同class节点的方法,本文讲解使用getELementsByClassName函数解决这个需求,并给了一个开源的getELementsByClassName函数实现,功能更加强大,需要的朋友可以参考下     网页开发时,在很多时候我们需要操作相同类名的元素,即class相同的元素.昨天参加笔试,有一道相关的题目没答上来: JavaScript获取页面中class为test的节点 于是收集了一些相关的资料,在本文中列举了两种我觉得比较

javascript 获取iframe里页面中元素值的方法

 本篇文章主要是对javascript获取iframe里页面中元素值的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 IE方法: document.frames['myFrame'].document.getElementById('test').value;   火狐方法: document.getElementById('myFrame').contentWindow.document.getElementById('test').value;   IE.火狐方法:   代码如