分享

使用 PHP 和 DHTML 设计 Web 2.0 应用程序,第 1 部分: 使用这些技术打造有特色的应用

 liu_jinbo 2006-09-16

2006 年 9 月 07 日  

2006 年最时髦的词莫过于 Web 2.0。Web 2.0 究竟意味着什么,这是一个热门的争论话题,但它似乎与一种很酷的动态 Web 应用程序有关。那些 Web 应用程序 —— 通常以 PHP 开发 —— 使用动态 HTML(DHTML)创建页面,移动及更改此页面时无需返回服务器进行更新。Jack Herrington 在 “使用 PHP 和 DHTML 设计 Web 2.0 应用程序” 系列文章中教您开始使用这项技术。

DHTML 是包含 JavaScript 代码的 HTML,这些代码可更改浏览器中的页面布局,而无需返回服务器。在您编写 HTML 页面时,您实际上是在编写一个对象树。所有标记 —— 小小的 <table><p> —— 都成为 JavaScript 空间中的对象。使用 JavaScript,您可以更改其内容、层叠样式表(Cascading Style Sheets,CSS)的式样以及位置 —— 均无需再返回服务器。DHTML 是 HTML、CSS 和 JavaScript 的交集。

自浏览器中添加了 JavaScript 代码后,使用 DHTML 的技术就已出现,但对此技术的支持一直参差不齐。早期,Microsoft? Internet Explorer 在这方面做得非常出色,但同一时期的 Netscape V4 缺乏支持。近来,Mozilla 和 Firefox 渐渐提供了可靠的 DHTML 支持。有些人认为形势已经与过去完全不同,Internet Explorer 现已在这方面落后。

DHTML 的优缺点

在您的页面中结合 JavaScript 将使页面具有动态性,并且能够带来更出色的用户体验。用户可更快地获得更多数据、从不同角度查看信息、无缝地在站点中导航 —— 而站点不必返回服务器处获得大量页面。

然而,也存在避免使用 JavaScript 的理由:浏览器兼容性。早期仅使用平面 HTML 时,Internet Explorer 呈现页面的方式与 Netscape 不同。那些问题已得到解决。但随着 CSS 支持的添加,出现了新的兼容性问题。如今,多半 CSS 问题已被解决,但又出现了 JavaScript 兼容性问题。

这些兼容性问题没有简单的解决方案。您需要根据需要测试和支持的浏览器的数量来衡量 JavaScript 的收益。

这里我们给出几条建议:

  • 使 JavaScript 尽可能地简单。
  • 发现兼容性问题时,首先上网查找最佳解决方法。您往往会找到经过精心研究的答案。
  • 拥有一个平面 HTML 代用系统,以应对您不支持的那些浏览器。
  • 保留一份支持的浏览器列表(及其版本号)。
  • 在 Mac 和 Microsoft Windows? 中查看 Internet Explorer。

本文的示例尽可能保持简单清楚。但仅在 Firefox 上进行了测试,所以会出现一些兼容性问题。本文将在出现兼容性问题的地方提醒您,以便您获得更多的实践经验。

实现 DHTML 最简便的方法就是首先在平面 HTML 页面中编写,不使用 PHP 或任何服务器端语言,随后以该代码作为 PHP 代码模板来生成 DHTML。通过这种方式,您可检查解决方案的基础,并将服务器的问题与客户机的问题区分开来。在本文中,每个示例都首先给出 HTML,随后再给出相应的 PHP 代码。





回页首


广告框

第一个示例简单且兼容:浮动广告框。图 1 展示了一个带有 Close 按钮的对话框,浮动于页面之上。


图 1. 浮动广告框
浮动广告框

用户可单击 Close 按钮关闭广告框,如图 2 所示。


图 2. 关闭广告框后的页面效果
关闭广告框后的页面效果

清单 1 为页面代码。


清单 1. 广告框代码
<html>
                        <head>
                        <title>Ad box demonstration</title>
                        <style>
                        body {
                        width: 800px;
                        }
                        .ad-box {
                        background: #eee;
                        border: 1px solid black;
                        padding: 5px;
                        position: absolute;
                        left: 50px;
                        top: 50px;
                        width: 600px;
                        }
                        .ad-box-title {
                        background: #ccc;
                        padding: 5px;
                        font-weight: bold;
                        font-size: large;
                        text-align: center;
                        text-transform: uppercase;
                        letter-spacing: 0.2em;
                        }
                        </style>
                        <script>
                        function closead()
                        {
                        var obj = document.getElementById( "ad" );
                        obj.style.visibility = "hidden";
                        }
                        </script>
                        </head>
                        <body>
                        <div class="ad-box" id="ad">
                        <div class="ad-box-title">
                        Special offer
                        </div>
                        <p>
                        You have been selected for our special offer. Can you imagine? What
                        are the odds? Just buy five hundred or more of our product and we
                        will give you a 1% discount on additional orders. Only the Department
                        of Defense gets deals like that!
                        </p>
                        <p style="text-align: right;">
                        <a href="javascript:closead();">close</a>
                        </p>
                        </div>
                        <p>This is our home page. Welcome to it. Here we talk about all of
                        our great products.</p>
                        <h1>Products</h1>
                        <p>This is a list of our products:</p>
                        <ul>
                        <li>The amazing all in one toothpix holder and axe grinder.</li>
                        <li>The complete Jean Claude Van Damme DVD collection.</li>
                        </ul>
                        </body>
                        </html>
                        

本例的大部分工作是使用 CSS 完成的。使用 position CSS 属性,使广告框浮在页面文本之上。lefttop 属性根据元素与页面左上角的相对位置定位元素。

为使广告框消失,您为 close 锚定标记编写了一些 JavaScript 代码。这里并未使用 http 协议,而是使用 javascript 协议,并调用了 closead 函数。closead JavaScript 函数获取 ad <div> 的对象引用,并改变 CSS 样式 visibility,从 visible 设置为 hidden,这样广告框就消失了。

本例展示了一些 DHTML 基本原理。首先是 id 属性的用法。为动态引用一个项目,通过 id 属性给予其一个惟一的 ID。在本例中,您为广告框设置的 ID 为 ad。随后使用 document.getElementById 方法获取广告框的 <div> 对象。

本例还示范了可在锚定标记中使用的 javascript 伪 URL。使用它,您可以在放置链接的任意位置调用 JavaScript。

这些技术兼容其他浏览器。所有现代浏览器均支持 JavaScript、CSS、绝对定位和在运行时对 visibility 属性这样的动态元素进行设置。





回页首


PHP 中的广告框

现在已经有了广告框的 DHTML 代码,接下来让我们看看如何在 PHP 中实现它(参见清单 2)。该广告框的惟一可选项就是显示与否。PHP 代码通过一个函数调用写出了广告框,根据环境决定是否调用页面。


清单 2. 广告框的 PHP 代码
<?php
                        function place_ad( $title )
                        {
                        ?>
                        <div class="ad-box" id="ad">
                        <div class="ad-box-title">
                        <?php echo( $title ); ?>
                        </div>
                        <p>
                        You have been selected for our special offer. Can you imagine? What
                        are the odds? Just buy five hundred or more of our product and we
                        will give you a 1% discount on additional orders. Only the Dept.
                        of Defense gets deals like that!
                        </p>
                        <p style="text-align: right;">
                        <a href="javascript:closead();">close</a>
                        </p>
                        </div>
                        <?php
                        }
                        ?>
                        <html>
                        <head>
                        <title>Ad box demonstration</title>
                        <style>
                        body {
                        width: 800px;
                        }
                        .ad-box {
                        background: #eee;
                        border: 1px solid black;
                        padding: 5px;
                        position: absolute;
                        left: 50px;
                        top: 50px;
                        width: 600px;
                        }
                        .ad-box-title {
                        background: #ccc;
                        padding: 5px;
                        font-weight: bold;
                        font-size: large;
                        text-align: center;
                        text-transform: uppercase;
                        letter-spacing: 0.2em;
                        }
                        </style>
                        <script>
                        function closead()
                        {
                        var obj = document.getElementById( "ad" );
                        obj.style.visibility = "hidden";
                        }
                        </script>
                        </head>
                        <body>
                        <?php place_ad( "Today‘s Special Offer!" ); ?>
                        <p>This is our home page. Welcome to it. Here we talk about all of
                        our great products.</p>
                        <h1>Products</h1>
                        <p>This is a list of our products:</p>
                        <ul>
                        <li>The amazing all in one toothpix holder and axe grinder.</li>
                        <li>The complete Jean Claude Van Damme DVD collection.</li>
                        </ul>
                        </body>
                        </html>
                        

全新的 place_ad PHP 函数通过灵活的 title 字符串将广告置于页面之上。为获得在多个页面上发布广告的能力,您可将此函数提取出来,放在一个单独的文件中,这样,每次需要在页面上插入广告时,只需包含此独立文件即可。





回页首


弹出框

浮动对话框主题的另一变种就是弹出框。您可使用弹出框提供用户请求的附加信息。考虑图 3 所示文本。


图 3. 关于动物的纯文本页面
关于动物的纯文本页面

如果用户能看到关于长颈鹿的更多信息,岂不是更好吗?文本包含一个便捷的链接,如果您单击此链接,将看到图 4 所示的弹出框。


图 4. 关于长颈鹿的更多信息
关于长颈鹿的更多信息

本例中,您应请求提供了一个对话框,并依据文档中的文本定位此对话框。代码如清单 3 所示。


清单 3. 弹出框的 HTML 代码
<html>
                        <head>
                        <title>Pop up Example</title>
                        <style type="text/css">
                        body { font-family: arial, verdana, sans serif; }
                        #popup {
                        position: absolute;
                        padding: 5px;
                        border: 1px solid black;
                        background: #eee;
                        left: 0px;
                        top: 0px;
                        visibility: hidden;
                        }
                        </style>
                        <script>
                        function popup( id )
                        {
                        var obj = document.getElementById( id );
                        var popup = document.getElementById( ‘popup‘ );
                        if ( popup.style.visibility == ‘visible‘ )
                        {
                        popup.style.visibility = ‘hidden‘;
                        }
                        else
                        {
                        popup.style.left = obj.offsetLeft + "px";
                        popup.style.top = ( obj.offsetTop + 20 ) + "px";
                        popup.style.visibility = ‘visible‘;
                        }
                        }
                        </script>
                        </head>
                        <body>
                        <div id="popup">
                        An animal with a very long neck.
                        </div>
                        <h2>Animals</h2>
                        A <a href="javascript:popup(‘word‘)" id="word">giraffe</a>
                        is a very interesting animal.
                        </body>
                        </html>
                        

本例中,包含弹出信息的 popup <div> 最初定义为 hidden,绝对位置为页面左上角。随后 giraffe 文字旁的锚定标记将调用 JavaScript 来显示弹出框。

popup JavaScript 方法使用 word ID 查找 giraffe 文本。随后使用 offsetLeftoffsetTop 值使弹出框恰好位于文本之下。若弹出框已为可见状态,则隐藏它。

您可在显示弹出框之前设置其内容,只需设置 popup <div> 对象的 innerHTML 成员即可。

此代码的兼容性相当好。但依然可能会出现问题,这是因为每个浏览器的 offsetLeftoffsetTop 值可能有所不同,对于带有复杂嵌套内容的页面而言更是如此。为在复杂页面中获得更准确的位置读数,您可能需要递归增加 offsetLeftoffsetTop 值,为此,使用 offsetParent 对象在您沿 HTML 对象树移动时获取各对象的父对象。





回页首


弹出框的 PHP 代码

有了 DHTML 代码后,即可更轻松地在 PHP 应用程序中使用弹出框。清单 4 给出了 PHP 代码。


清单 4. 弹出框的 PHP 代码
<?php
                        function popup_header()
                        {
                        ?>
                        <style type="text/css">
                        body { font-family: arial, verdana, sans serif; }
                        #popup {
                        position: absolute;
                        padding: 5px;
                        border: 1px solid black;
                        background: #eee;
                        left: 0px;
                        top: 0px;
                        visibility: hidden;
                        }
                        </style>
                        <script>
                        function popup( id, info )
                        {
                        var obj = document.getElementById( id );
                        var popup = document.getElementById( ‘popup‘ );
                        if ( popup.style.visibility == ‘visible‘ )
                        {
                        popup.style.visibility = ‘hidden‘;
                        }
                        else
                        {
                        popup.innerHTML = info;
                        popup.style.left = obj.offsetLeft + "px";
                        popup.style.top = ( obj.offsetTop + 20 ) + "px";
                        popup.style.visibility = ‘visible‘;
                        }
                        }
                        </script>
                        <?php
                        }
                        function popup( $id, $text, $info )
                        {
                        ?>
                        <a href="javascript:popup(‘<?php echo($id) ?>‘,‘<?php echo($info) ?>‘)"
                        id="<?php echo($id) ?>"><?php echo($text) ?></a>
                        <?php
                        }
                        ?>
                        <html>
                        <head>
                        <title>Pop up Example</title>
                        <?php popup_header(); ?>
                        </head>
                        <body>
                        <div id="popup">
                        </div>
                        <h2>Animals</h2>
                        A
                        <?php popup( ‘word‘, ‘giraffe‘,
                        ‘An animal with a very long neck.‘ ) ?>
                        is a very interesting animal.
                        </body>
                        </html>
                        ?tml>
                        

在本例中,您将标题的生成与各弹出框的放置相分离。页面必须调用 head 标记中的 popup_header,然后添加 id 值为 popup<div> 标记。随后,只要需要弹出框,页面就会调用 PHP 函数 popup

PHP 函数 popup 接受 3 个参数:弹出框的 ID、纯文本版本以及单击项目时弹出的文本。函数随后会呈现一个锚定标记,其外观几乎与原 DHTML 中的版本完全相同。

由于一个页面上可能会显示多个弹出框,所以添加了第三个参数以提供弹出框中显示的文本。为实现这一功能,为 JavaScript 函数 popup 再添加一个参数。<div> 标记的 innerHTML 随后会设置为这个新参数的内容。





回页首


微调控制项

在页面中隐藏和显示数据的另一选择就是微调控制项(spinner)。在此模型中,页面划分为几部分,各部分可使用微调控制项独立隐藏或显示。图 5 展示了带有两部分微调控制项的页面,各部分最初都是关闭的。


图 5. 各微调控制项部分均关闭的页面
各微调部分均关闭的页面

单击 Level One 部分中的 Open 链接将显示此部分的内容,如图 6 所示。


图 6. 展开了第一个微调控制项部分的页面
展开了第一个微调控制项部分的页面

您可以使用图形来取代文字 openclosed。按照惯例,通常使用向右的三角形取代 closed,向下的三角形取代 open;也可使用加减号,加号表示 closed,减号表示 open。(对于哪种方式更好的评价涉及到 Mac 与 Windows 对比的争论。这两个平台上的微调控制项正与这两种不同的方式分别对应。)

清单 5 中的代码展示了这些微调控制项的工作原理:


清单 5. 微调控制项的 HTML 代码
<html>
                        <head>
                        <title>Spinner Example</title>
                        <style type="text/css">
                        body { font-family: arial, verdana, sans serif; width: 800px; }
                        .item-header a { font-size: small; }
                        .item-header {
                        font-weight: bold; border-bottom: 1px solid black;
                        font-size: x-large;
                        }
                        .item-body {
                        margin: 0px; font-size: small;
                        visibility: hidden; height: 0px;
                        }
                        </style>
                        <script>
                        function spin( obj )
                        {
                        var spinner = document.getElementById( obj );
                        var spinner_content = document.getElementById( obj+"_body" );
                        if ( spinner_content.style.visibility == ‘visible‘ )
                        {
                        spinner.innerHTML = ‘open‘;
                        spinner_content.style.visibility = ‘hidden‘;
                        spinner_content.style.height = ‘0px‘;
                        spinner_content.style.margin = ‘0px‘;
                        }
                        else
                        {
                        spinner.innerHTML = ‘close‘;
                        spinner_content.style.visibility = ‘visible‘;
                        spinner_content.style.height = ‘auto‘;
                        spinner_content.style.margin = ‘20px 0px 20px 50px‘;
                        }
                        }
                        </script>
                        </head>
                        <body>
                        <div class="item-header">
                        <a href="javascript:spin(‘lev1‘)" id="lev1">open</a> Level One
                        </div>
                        <div class="item-body" id="lev1_body">
                        This is the content of level one.
                        </div>
                        <div class="item-header">
                        <a href="javascript:spin(‘lev2‘)" id="lev2">open</a> Level Two
                        </div>
                        <div class="item-body" id="lev2_body">
                        This is the content of level two.
                        </div>
                        </body>
                        </html>
                        

两组 <div> 定义了各部分及其内容。按照惯例,为标题赋予 ID lev 加上一个数字(例如,lev2),正文使用相同的 ID 加后缀 _bodylev2 是微调控制项的链接,lev2_body 是该项目的正文。

微调控制项的智能部分是在 spin 函数中实现的,它查看微调控制项正文部分的可见性,并加以转换,将可见转变为隐藏、隐藏转变为可见。

在项目不可见时,将 height 属性设置为 0px,而在项目可见时将此属性设置为 auto。对于 Internet Explorer,项目不可见时,其空间也会随之折叠。但对于 Firefox,内容不可见时,其空间依然作为占位符存在。您需要将 height 设置为 0px,才能使空间正确地折叠起来。

为使用图形取代文本来表示展开和关闭状态,更改代码,改变微调控制项对象的 innerHTML 值,使其指定一个图像标记而非文本。





回页首


微调控制项的 PHP 代码

为在 PHP 中实现微调控制项,采用服务器端创建 DHTML 代码的标准模式即可,在 start 和 end 函数中划分 HTML 的各部分。PHP 代码如清单 6 所示。


清单 6. 微调控制项的 PHP 代码
<?php
                        function start_spinner( $id, $title )
                        {
                        ?>
                        <div class="item-header">
                        <a href="javascript:spin(‘<?php echo( $id ); ?>‘)"
                        id="<?php echo( $id ); ?>">open</a> <?php echo( $title ); ?>
                        </div>
                        <div class="item-body" id="<?php echo( $id ); ?>_body">
                        <?php
                        }
                        function end_spinner()
                        {
                        ?>
                        </div>
                        <?php
                        }
                        ?>
                        <html>
                        <head>
                        <title>Spinner Example</title>
                        <style type="text/css">
                        body { font-family: arial, verdana, sans serif; width: 800px; }
                        .item-header a { font-size: small; }
                        .item-header {
                        font-weight: bold; border-bottom: 1px solid black;
                        font-size: x-large;
                        }
                        .item-body {
                        margin: 0px; font-size: small;
                        visibility: hidden; height: 0px;
                        }
                        </style>
                        <script>
                        function spin( obj )
                        {
                        var spinner = document.getElementById( obj );
                        var spinner_content = document.getElementById( obj+"_body" );
                        if ( spinner_content.style.visibility == ‘visible‘ )
                        {
                        spinner.innerHTML = ‘open‘;
                        spinner_content.style.visibility = ‘hidden‘;
                        spinner_content.style.height = ‘0px‘;
                        spinner_content.style.margin = ‘0px‘;
                        }
                        else
                        {
                        spinner.innerHTML = ‘close‘;
                        spinner_content.style.visibility = ‘visible‘;
                        spinner_content.style.height = ‘auto‘;
                        spinner_content.style.margin = ‘20px 0px 20px 50px‘;
                        }
                        }
                        </script>
                        </head>
                        <body>
                        <?php start_spinner( ‘lev1‘, "Level One" ); ?>
                        This is the content of level one.
                        <?php end_spinner( ); ?>
                        <?php start_spinner( ‘lev2‘, "Level Two" ); ?>
                        This is the content of level two.
                        <?php end_spinner( ); ?>
                        </body>
                        </html>
                        

通过调用 start_spinnerend_spinner 划分内容的各部分。start_spinner 函数接受两个参数:微调控制项的 ID 及其标题。end_spinner 调用结束 start_spinner 中打开的 <div> 标记,以容纳微调控制项的内容。

您可将微调控制项的内容作为第三个参数引入。但在一般情况下,这些内容部分形式复杂,若您以这种方式编写代码,界面使用起来将非常困难。在 start 和 end 函数中划分动态部分的模式意味着您可以随意选择其中 PHP 的复杂度。





回页首


选项卡

选项卡是查看内容不同部分的另一种常见方法。在 MetaCritic 站点上可以看到选项卡的轻量级版本(参见 参考资料),该站点使用选项卡切换游戏列表的查看方式 —— 按名称查看或按评价分数查看,而且不必返回服务器。图 7 展示了此游戏列表的简化示例。


图 7. 按名称排列的游戏
按名称排列的游戏

若要查看按评价分数排列的游戏,单击 By Score 链接。列表会发生变化,如图 8 所示。


图 8. 按分数排列的游戏
按分数排列的游戏

MetaCritic 站点没有在客户端进行复杂的排序,而是使用了相当于 flash 卡的一种方式:一个选项卡上的列表按名称排列,另外一个选项卡按分数排列。单击链接时,则隐藏一个选项卡,显示另外一个选项卡。代码如清单 7 所示。


清单 7. 选项卡的 HTML 代码
<html>
                        <head>
                        <title>Tabs Example</title>
                        <style type="text/css">
                        body { font-family: arial,verdana,sans serif; }
                        .button-on, .button-off { padding: 3px; border: 1px solid black; }
                        .button-on { background: #333; color: white; font-weight: bold; }
                        .game-list { position: absolute; top: 0px; left: 0px; }
                        .container { padding: 5px; border: 1px solid black; margin: 5px;
                        position: relative; height: 400px; width: 200px; }
                        </style>
                        <script>
                        function show( divid )
                        {
                        var tos = [ "names", "score" ];
                        for( var t in tos )
                        {
                        var to = document.getElementById( tos[t] );
                        to.style.visibility = "hidden";
                        to.style.height = "0px";
                        var bo = document.getElementById( tos[t]+"-button" );
                        bo.className = "button-off"
                        }
                        var to = document.getElementById( divid );
                        to.style.visibility = "visible";
                        to.style.height = "auto";
                        var bo = document.getElementById( divid + "-button" );
                        bo.className = "button-on";
                        }
                        </script>
                        </head>
                        <body onload="show(‘names‘)">
                        Sort by:
                        <a href="javascript:show(‘names‘)" id="names-button"
                        class="button-on">By Name</a>
                        <a href="javascript:show(‘score‘)" id="score-button"
                        class="button-off">By Score</a><br/>
                        <div class="container">
                        <div id="names" class="game-list">
                        <table width="100%">
                        <tr><td>Crank Shaft</td><td>22</td></tr>
                        <tr><td>Driver</td><td>42</td></tr>
                        <tr><td>Football 2006</td><td>72</td></tr>
                        <tr><td>Soccer 2006</td><td>99</td></tr>
                        <tr><td>Xevious</td><td>32</td></tr>
                        </table>
                        </div>
                        <div id="score" class="game-list">
                        <table width="100%">
                        <tr><td>Crank Shaft</td><td>22</td></tr>
                        <tr><td>Xevious</td><td>32</td></tr>
                        <tr><td>Driver</td><td>42</td></tr>
                        <tr><td>Football 2006</td><td>72</td></tr>
                        <tr><td>Soccer 2006</td><td>99</td></tr>
                        </table>
                        </div>
                        </div>
                        </body>
                        </html>
                        

两个列表分别位于两个 <div> 标记中:namesscorenames <div> 拥有按名称排序的游戏列表,score 拥有按分数排序的列表。show 函数连接到 By Name 和 By Score 链接,首先使所有列表均不可见,随后使所选列表可见。

还有其他一些有趣的东西。首先,您使用 className 属性动态地更改了链接的 CSS 类。这也就是所选按钮从白色变为黑色的原因。

其次,观察 namesscore 的 CSS。两个 <div> 均按绝对位置定位于左上部,但不在页面的左上角。这是因为它们位于 ID 值为 container<div> 中,而 container 的位置设置为 relativecontainer <div> 有效地重置了包含于其中的项目的原点。表格是相对于容器而不是页面来定位的。

这种 DHTML 不但复杂度合理、有趣,而且几乎与所有现代浏览器兼容。





回页首


选项卡的 PHP 代码

在 PHP 中开发 DHTML 的另外一种工具就是输出缓存区 的使用。输出缓存区存储页面中的文本、选项卡和重复素材,并将其作为字符串返回,供以后使用。为实现选项卡,将使用输出缓存区,在把选项卡内容呈现到页面中之前将其作为字符串存储(参见清单 8)。


清单 8. 选项卡的 PHP 代码
<?php
                        $tabs = array();
                        $current_tab = null;
                        function start_tab( $id, $title )
                        {
                        global $tabs, $current_tab;
                        ob_start();
                        $current_tab = $id;
                        $tabs[ $id ] = array( ‘title‘ => $title, ‘html‘ => "" );
                        }
                        function end_tab()
                        {
                        global $tabs, $current_tab;
                        $tabs[ $current_tab ][ ‘html‘ ] = ob_get_contents();
                        ob_end_clean();
                        }
                        function get_tab_ids()
                        {
                        global $tabs;
                        $ids = array();
                        foreach( $tabs as $tabid => $tab ) {
                        $ids []= "‘".$tabid."‘";
                        }
                        return $ids;
                        }
                        function get_first_tab()
                        {
                        $tabs = get_tab_ids();
                        return $tabs[0];
                        }
                        function place_tab_buttons()
                        {
                        global $tabs;
                        foreach( $tabs as $tabid => $tab ) {
                        ?>
                        <a href="javascript:show(‘<?php echo($tabid); ?>‘)"
                        id="<?php echo($tabid); ?>-button"
                        class="button-off"><?php echo( $tab[‘title‘] ); ?></a>
                        <?php
                        }
                        }
                        function place_tab_content()
                        {
                        global $tabs;
                        foreach( $tabs as $tabid => $tab ) {
                        ?>
                        <div id="<?php echo($tabid); ?>" class="game-list">
                        <?php echo( $tab[‘html‘] ); ?>
                        </div>
                        <?php
                        }
                        }
                        ?>
                        <?php start_tab( ‘names‘, "By Name" ); ?>
                        <table width="100%">
                        <tr><td>Crank Shaft</td><td>22</td></tr>
                        <tr><td>Driver</td><td>42</td></tr>
                        <tr><td>Football 2006</td><td>72</td></tr>
                        <tr><td>Soccer 2006</td><td>99</td></tr>
                        <tr><td>Xevious</td><td>32</td></tr>
                        </table>
                        <?php end_tab( ); ?>
                        <?php start_tab( ‘scores‘, "By Score" ); ?>
                        <table width="100%">
                        <tr><td>Crank Shaft</td><td>22</td></tr>
                        <tr><td>Xevious</td><td>32</td></tr>
                        <tr><td>Driver</td><td>42</td></tr>
                        <tr><td>Football 2006</td><td>72</td></tr>
                        <tr><td>Soccer 2006</td><td>99</td></tr>
                        </table>
                        <?php end_tab( ); ?>
                        <html>
                        <head>
                        <title>Tabs Example</title>
                        <style type="text/css">
                        body { font-family: arial,verdana,sans serif; }
                        .button-on, .button-off { padding: 3px; border: 1px solid black; }
                        .button-on { background: #333; color: white; font-weight: bold; }
                        .game-list { position: absolute; top: 0px; left: 0px; }
                        .container { padding: 5px; border: 1px solid black; margin: 5px;
                        position: relative; height: 400px; width: 200px; }
                        </style>
                        <script>
                        function show( divid )
                        {
                        var tos = [ <?php echo( join( ",", get_tab_ids() ) ); ?> ];
                        for( var t in tos )
                        {
                        var to = document.getElementById( tos[t] );
                        to.style.visibility = "hidden";
                        to.style.height = "0px";
                        var bo = document.getElementById( tos[t]+"-button" );
                        bo.className = "button-off"
                        }
                        var to = document.getElementById( divid );
                        to.style.visibility = "visible";
                        to.style.height = "auto";
                        var bo = document.getElementById( divid + "-button" );
                        bo.className = "button-on";
                        }
                        </script>
                        </head>
                        <body onload="show(<?php echo( get_first_tab() ); ?>)">
                        Sort by:
                        <?php place_tab_buttons() ?>
                        <div class="container">
                        <?php place_tab_content() ?>
                        </div>
                        </body>
                        </html>
                        

PHP 代码首先定义了两个变量:tabscurrent_tabtabs 数组保存各选项卡的 idtitlehtml 值。current_tab 指向 start_tabend_tab 调用间创建的选项卡。start_tab 函数接受两个参数:选项卡的 id 值和 title 值。它随后会启动输出缓存。

end_tab 函数终止输出缓存,并将作为结果的 HTML 存储在 tabs 数组的 current_tabhtml 值中。

再往下看,可以看到 start_tabend_tab 调用中包含要在选项卡中呈现的选项卡内容。

将选项卡呈现在页面上的重要函数就是 place_tab_buttonsplace_tab_contentplace_tab_buttons 函数创建有着选项卡名称的锚定标记,单击锚定标记时,将切换选项卡。place_tab_content 函数创建具有输出缓存区存储的各选项卡内容的 <div> 标记。

get_tab_idsget_first_tab 是创建 JavaScript 的辅助函数。它们分别返回选项卡 ID 的完整列表和第一个选项卡的 ID。





回页首


下期预告

使用 PHP 和 DHTML 设计 Web 2.0 应用程序” 系列的下一篇文章将介绍通过 JavaScript 生成动态图片的内容。下篇文章将教您如何动态创建新的 HTML 元素,并在 PHP 应用程序所显示的页面中定位这些元素。





回页首


参考资料

学习

获得产品和技术
  • 使用 IBM 试用软件 革新您的下一个开放源码开发项目,可通过下载获得,也可通过 DVD 获得。


讨论




回页首


关于作者

Jack D. Herrington 是一名高级软件工程师,有着二十余年的经验。他撰写了三本图书:Code Generation in ActionPodcasting Hacks 和即将出版的 PHP Hacks。他的作品还包括三十多篇文章。






回页首

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约