热门文章 | 热门软件| 热门源码 | 热门电影 | 知识库 | 联系我们
软件 源码 教程 影视 健康 招聘
  HTML | JavaScript | ASP | PHP | JSP | NET | VB | VC | VF | Windows | Linux | Mysql | Mssql | Oracle | Struts 
当前位置: 创世纪计算机资源网 -> 文章频道 ->html 
站内搜索:
层的隐藏和显示二(1)
作者:apple 来源:apple.com.cn 整理日期:2007-7-10

     有些事情现在已经很容易被忘记了,但是在开发原创的 Mac OS 的时候,业界到处出现新的图形用户接口(GUI),人们所做的工作差别相当小。Macintosh 的设计团队在很多事情上是正确的,这很大程度上是因为他们在自己正在干什么这个问题上付出了难以想像的思考。虽然要为 Internet Developer(英特网开发者)书写一些脚本方面的集体思想,但还是想去看一些过去的 Macintosh 人机界面指南,并且看看这些指导原则如何才能用到 Web 界面上,认为这是很值当的。很少去找可以拷贝的具体部件,而更多地寻找这个以友好闻名的界面后面隐藏的设计原则。

     原则之一就是无模式。这个原则打动了,因为它特别适合于 Web。正如 Mac 的设计者描述的那样,模式界面(在这种界面下,您能做什么取决于您当前处于什么模式下)会“把用户锁定在一个操作上,用户在该操作完成之前不允许进行其它任何操作”。使用单纯的老版本HTML时,从某种意义上看,所有界面都是模式的,进行任何修改都需要装载一个新的页面。举例来说,假定您在填充一个表单时需要一些帮助,则您必须转到包含帮助信息的新页面,然后再回到原来的页面,以完成表单的填写。

     换句话说,您或者处于“帮助”模式,或者处于“表单填写”模式。这凸显了 Web 的两个主要的限制:无态(即当点击帮助连接时,您在表单中已经输入的信息将会丢失)和迟延(即您必须等待页面装载)。因此决定写一点脚本来帮助处理这些问题。这些脚本通过动态 HTML (DHTML)技术在您点击连接时弹出一个带有帮助信息的方框。在演示中,就是使用它们来弹出与表单填写相关的上下文帮助信息。这些脚本也可以用在别的地方,比如弹出一篇论文的术语定义。上述的两种情况都以合理的方式给出了上下文相关的信息,即无模式的方式。同时,这个解决方案也避免了无态和迟延的问题。

     实际上,写的这些基本函数可以用在任何需要在页面上移动和改变对象可视性的地方。做了一个快速下拉菜单的实例,就是为了演示同样这些代码的另外一种使用方式,您可能会用得到。

     您可能会担心有人还在使用版本比较老的浏览器,对此,们可以相当轻松地使这些脚本自然地回退到原来的状态,使那些使用老版本浏览器的用户可以简单地从一个单独的页面上获得信息。将在下面的“如何使用脚本”的部分中解释如何实现这个目标。

脚本的目标

     这个脚本将创建动态菜单和弹出式对象。它包括一些跨浏览器的基本函数,用于移动和改变DHTML对象的可视性。在 Netscape 4.x 中,一个 DHTML 对象是一个通过绝对位置定位的 DIV,而对 Safari,Internet Explorer 4 和 5,或者 Netscape 6 来说,则是任何 HTML 元素。这些函数可以被用在大量的 DHTML 应用中;这里还给出的两个实例,向您演示如何创建一个弹出式的提示(tip)和下拉式菜单。脚本中的主要函数如下:

  • changeObjectVisibility,用来翻转一个 DHTML 对象的可视性。
  • moveObject,用来在浏览器窗口中把一个 DHTML 对象移动到特定的位置上。
  • getStyleObject,这个函数通过获得一个风格对象的引用简化了跨浏览器的 DTHML,们可以从这个对象中读取属性,或者进行属性设定,包括位置,可视性,颜色,尺寸,等等。

编码的挑战

遗憾的是,由于长期以来浏览器都是由各个厂商自行实现,所以书写跨浏览器和跨平台的 DHTML 通常是拜占庭式的条件分支。为任何一个浏览器书写这些脚本都是非常轻松的;为了使它们工作在 Netscape 4 及其升级版本,以及工作在 Internet Explorer 4 及其升级版本上,事情就要复杂一些了;而使它们可以回退到比较老版本的浏览器的状态,又增加了更多的复杂度。问题在于各个浏览器在如何寻找和操作 Web 页面上的对象方面都有很多独特之处,虽然们对这种状态已经比较熟悉了。为了方便,写了处理这些条件分支的代码。

这些函数中有一些功能不能工作在更老一些的浏览器上,比如 Netscape 3。然而,使这些功能自然地退化并补台困难。您只需进行如下操作:

  • 直接把这些脚本包含在页面上,而不是使用连接的 .js 文件。
  • 只在提供相关支持的浏览器上使用 JavaScript 进行弹出式的 DIV 的输出。实现这个控制的代码大致如下:
    if(document.getElementById || document.all
      || document.layers) {
      // write out div tag with document.write
    }

发现的最大挑战是必须考虑浏览器处理事件的不同方式。事件发生时(比如 click 或者 mouseover 事件)光标的位置存储在一个事件对象中,而不同浏览器对事件对象的处理有轻微的不同。当事件发生时,Netscape 4 和6都产生一个新的事件对象,您可以把这个对象作为一个参数传递到函数中;而 Internet Explorer 则使用一个独立的全局 window.event 对象。对于这个问题,在抛弃几个现在看来很草率的解决方案之后,发现把事件对象显式地传递给函数的做法可以适用于这两种浏览器:

<a href="#" onclick="showPopup(popupName,
  event);">click</a>

请注意,在事件边上少了引号标识。那是因为它是一个对象,而不是文本。现在,在您的函数中就可以以如下方式使用传入的事件对象了:

function showPopup(nameOfPopup, eventObject) {
  alert(eventObject.clientX);
}

一旦把对象传递给函数,您就可以通过读取 pageXpageY 属性(Netscape 4 和 6)或者 clientXclientY 属性(IE 4+)来获得光标的位置。然而请注意,clientXclientY 属性并没有考虑页面可能被滚动的情况,因为这两个坐标是相对于窗口的左上角的,而不是整个文档。为了解决这个问题,们加上 IE 的 document.body.scrollLeft document.body.scrollTop 属性的值。如果您感兴趣的话,事件对象还有一连串有用的属性,包括一个事件触发对象的引用(在 IE 上是 srcElement,而在 Netscape 上则是 target)。

把事件对象作为参数进行传递的唯一麻烦是在不支持事件对象的老版本浏览器上不能工作。为了绕开这个问题,们在 popup.js 文件中包含一个函数,该函数为那些不存在事件对象的浏览器创建一个假的对象,在装载文档时运行:

function createFakeEventObj() {
// create a fake event object for older browsers
//to avoid errors in function call when we 
//need to pass the event object
    if (!window.event) {
        window.event = false;
    }
}

这个函数把 window.event 设定为 false(假)。这样以后,们就可以在使用之前进行检测,看看是否存在真正的事件对象。

在 Mac 版的 Internet Explorer 5 上有一个问题,即当弹出层出现在文本的上方时,只有部分内容可以被显示。但是当移动 DIV 标识,使之成为文档体的第一个元素时,这个问题神秘地消失了。

还是在 Mac 版的 IE 5 上,由于某些原因,document.onclick 事件只有在页面上存在实际文本时才能被触发。为了绕过这个缺陷(以便使您可以通过点击窗口中的任意位置来关闭窗口),在页面中增加了一个不包含任何内容的,通过绝对位置定位的 DIV,然后用 JavaScript 来改变这个 DIV 的尺寸,使之覆盖整个窗口。相关的代码大致如下:

function resizeBlankDiv() {
// resize blank placeholder div so IE 5
// on mac will get all clicks in window
if ((navigator.appVersion.indexOf(MSIE 5) != -1)
  && (navigator.platform.indexOf(Mac) != -1)
  && getStyleObject(blankDiv)) {
    getStyleObject(blankDiv).width =
      document.body.clientWidth - 20;
    getStyleObject(blankDiv).height = 
      document.body.clientHeight - 20;
  }
}

遗憾的是,如果浏览器的尺寸被改变了,则只有一种方法可以恢复尺寸,即重新装载整个文档(您可能认为,只要用 window.onresize 事件就可以了。然而由于这个事件在窗口的尺寸真正被改变之前就已经发生了,所以采用这种方法最终会产生不必要的滚动条)。为了恢复页面尺寸,们又写了一个函数,在窗口尺寸被改变的任何时候,该函数可以从 Mac 平台上的 IE5 的缓存中重新装载页面。

在 Mac 版的 Internet Explorer 5 上,当您点击一个连接时,会出现一个绝对大的轮廓,这个轮廓会和将要弹出的内容相重叠。为了解决这个问题,在连接上增加了一条风格规则:

.popupLink { outline: none }

Netscape 4 在 DIV 的命名上有一些怪异的问题。以数字开头的名称(比如“1div”),以及有些带有下划线的名称(比如“my_div”)不能转化为层,因此通常都避免这两种情况,把的 DIV 按类似于 myDiv 或者 div1 的形式来命名。

Netscape 4 还有一个严重的缺陷,即当窗口的尺寸被改变时,所有的风格规则都会丢失。没有把修复这个缺陷的代码包含进来,因为已经有好几个这样的代码公布出来了,比如 Webmonke 上的这个.

最后,在 Netscape 4 中,如果您把 javascript: 放在 hrefs 中,会导致页面的重新装载,并把函数的返回值当成页面的唯一内容显示出来。因此们不应该采取下面的方式:

[1]  [2]  
相关文章