打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用 PHP 和 DHTML 设计 Web 2.0 应用程序,第 2 部分: 使用 JavaScript 创建 HTML 动态元素

Jack Herrington (jack_d_herrington@codegeneration.net), 高级软件工程师, "Code Generation Network"

2006 年 9 月 07 日

使用 PHP 和 DHTML 设计 Web 2.0 应用程序” 系列文章的第 1 部分探讨了如何使用 JavaScript、层叠样式表(CSS) 和 HTML 构建带有选项卡、微调控制项、弹出框等用户界面元素的 PHP 应用程序。第 2 部分将扩展上一篇文章的内容,将图形技术包含在内,使用 JavaScript 动态创建新的 HTML 元素。

第 1 部分 介绍了移动、隐藏和显示 Web 页面内容的方法。但如何动态创建新的 HTML 元素呢?该如何图形化数据及使用类似的有趣技术呢?图 1 展示了全世界文盲率的图表(数据来自 Unesco,请参阅 参考资料)。


图 1. 按年份排列的全球文盲率


这并非最有趣的数据集,但振奋人心。那么如果只想查看欧洲的文盲率呢?非常简单:单击下拉菜单,选择 Europe 即可。


图 2. 按年份排列的欧洲文盲率


图表显示出,欧洲的文盲率远远低于全球水平。清单 1 给出了产生此动态图表的代码。


清单 1. 条形图代码
<html>
                        <head>
                        <title>Bar Graph Example</title>
                        <script>
                        var years = [ 1970, 1980, 1990, 1995, 2000, 2005, 2010, 2015 ];
                        var rates = [];
                        rates[ ‘World‘ ] = [ 36.6, 30.3, 24.7, 22.4,
                        20.3, 18.3, 16.5, 15.0 ];
                        rates[ ‘Africa‘ ] = [ 72.4, 62.4, 51.2, 45.6,
                        40.2, 35.2, 30.8, 26.8 ];
                        rates[ ‘America‘ ] = [ 14.8, 11.6, 9.0, 7.9,
                        6.9, 6.0, 5.3, 4.6 ];
                        rates[ ‘Asia‘ ] = [ 48.5, 38.7, 30.2, 27.2,
                        24.4, 21.8, 19.6, 17.7 ];
                        rates[ ‘Europe‘ ] = [ 6.4, 4.3, 2.8, 2.2, 1.8,
                        1.4, 1.1, 0.8 ];
                        rates[ ‘Oceania‘ ] = [ 11.1, 8.7, 7.1, 6.6,
                        6.1, 5.6, 5.3, 5.0 ];
                        function plot( region )
                        {
                        var html = "";
                        html += "<table width=‘100%‘ cellspacing=‘0‘ cellpadding=‘1‘>";
                        for( var year in years )
                        {
                        var val = Math.round( rates[region][year] );
                        html += "<tr>";
                        html += "<td width=‘8%‘>"+years[year]+"</td>";
                        html += "<td width=‘1%‘ class=‘bar-start‘></td>";
                        html += "<td width=‘92%‘>";
                        html += "<table width=‘100%‘ cellspacing=‘0‘ ";
                        html += "cellpadding=‘0‘><tr>";
                        html += "<td width=‘"+val+"%‘ class=‘bar-on‘>";
                        html += " </td>";
                        html += "<td width=‘"+(100-val);
                        html += "%‘ class=‘bar-off‘> </td>";
                        html += "</tr></table></td>";
                        html += "<td width=‘1%‘ class=‘bar-start‘></td>";
                        html += "</tr>";
                        }
                        html += "</table>";
                        document.getElementById( "graph" ).innerHTML = html;
                        }
                        </script>
                        <style>
                        body { font-family: arial, verdana, sans serif; }
                        .bar-on { background: blue; }
                        .bar-off { background: white; }
                        .bar-start { width:1px; background: black; }
                        #graph { width: 600px; }
                        </style>
                        </head>
                        <body onload="plot(‘World‘)">
                        Region:
                        <select onchange="plot(this.options[this.selectedIndex].value)">
                        <option value="World">World</option>
                        <option value="Africa">Africa</option>
                        <option value="America">America</option>
                        <option value="Asia">Asia</option>
                        <option value="Europe">Europe</option>
                        <option value="Oceania">Oceania</option>
                        </select><br/><br/>
                        Rates of illiteracy (larger is worse):<br/><br/>
                        <div id="graph">
                        </div>
                        </body>
                        </html>
                        

首先给出了一个 ID 为 "graph" 的空 <div><body> 标记的 onload 属性告诉浏览器在载入页面时调用 plot 函数。这段代码有趣的地方就在于 plot 函数。

此函数首先创建了一个空字符串。接下来,它通过在字符串中添加 <table><tr><td> 标记构建图表。此函数随后将 graph <div> 标记的 innerHTML 属性设置为新生成的 HTML。

图形本身是一个表,有四列:年份、小分隔符、条形图及另外一个分隔符。条形符列的各行中是另外一个表。这些嵌套表有两个单元格:第一个单元格为蓝色,第二个单元格为白色。蓝色单元格的宽度为文盲率,白色单元格的宽度为 100% 减文盲率。结果得到简单的 HTML 条形图,没有任何图像。

Region 下拉菜单有一个 onchange 处理程序,只要选中新项目,此处理程序就会被调用。此时,以当前选中的值调用 plot 方法,图形即被更新。

此代码的兼容性非常好。所使用的 innerHTML 可用 createElementappendChild 等 DOM 方法取代,可兼容所有现代浏览器。

条形图的 PHP 代码

在 PHP 中实现条形图时,本文着眼于如何从服务器的 PHP 代码中获取数据并将其置入 Dynamic HTML(DHTML)JavaScript 中。条形图的 PHP 代码如清单 2 所示。


清单 2. 条形图的 PHP 代码
<?php
                        $years = array( 1970, 1980, 1990, 1995, 2000, 2005, 2010, 2015 );
                        $countries = array();
                        $countries[ "World" ] = array( 36.6, 30.3, 24.7, 22.4,
                        20.3, 18.3, 16.5, 15.0 );
                        $countries[ "Africa" ] = array( 72.4, 62.4, 51.2, 45.6,
                        40.2, 35.2, 30.8, 26.8 );
                        $countries[ "America" ] = array( 14.8, 11.6, 9.0, 7.9,
                        6.9, 6.0, 5.3, 4.6 );
                        $countries[ "Asia" ] = array( 48.5, 38.7, 30.2, 27.2,
                        24.4, 21.8, 19.6, 17.7 );
                        $countries[ "Europe" ] = array( 6.4, 4.3, 2.8, 2.2,
                        1.8, 1.4, 1.1, 0.8 );
                        $countries[ "Oceania" ] = array( 11.1, 8.7, 7.1, 6.6,
                        6.1, 5.6, 5.3, 5.0 );
                        ?>
                        <html>
                        <head>
                        <title>Bar Graph Example</title>
                        <script>
                        var years = [ <?php echo( join( ",", $years ) ); ?> ];
                        var rates = [];
                        <?php
                        foreach( $countries as $name => $values ) {
                        ?>
                        rates[ ‘<?php echo($name) ?>‘ ] = [
                        <?php echo( join( ",", $values ) ); ?> ];
                        <?php } ?>
                        function plot( region )
                        {
                        var html = "";
                        html += "<table width=‘100%‘ cellspacing=‘0‘ cellpadding=‘1‘>";
                        for( var year in years )
                        {
                        var val = Math.round( rates[region][year] );
                        html += "<tr>";
                        html += "<td width=‘8%‘>"+years[year]+"</td>";
                        html += "<td width=‘1%‘ class=‘bar-start‘></td>";
                        html += "<td width=‘92%‘>";
                        html += "<table width=‘100%‘ cellspacing=‘0‘ cellpadding=‘0‘><tr>";
                        html += "<td width=‘"+val+"%‘ class=‘bar-on‘> </td>";
                        html += "<td width=‘"+(100-val)+"%‘ class=‘bar-off‘> </td>";
                        html += "</tr></table></td>";
                        html += "<td width=‘1%‘ class=‘bar-start‘></td>";
                        html += "</tr>";
                        }
                        html += "</table>";
                        document.getElementById( "graph" ).innerHTML = html;
                        }
                        </script>
                        <style>
                        body { font-family: arial, verdana, sans serif; }
                        .bar-on { background: blue; }
                        .bar-off { background: white; }
                        .bar-start { width:1px; background: black; }
                        #graph { width: 600px; }
                        </style>
                        </head>
                        <body onload="plot(‘World‘)">
                        Region: <select onchange="plot(this.options[this.selectedIndex].value)">
                        <?php
                        foreach( $countries as $name => $values ) {
                        ?>
                        <option value="<?php echo($name) ?>"><?php echo($name) ?></option>
                        <?php } ?>
                        </select><br/><br/>
                        Rates of illiteracy (larger is worse):<br/><br/>
                        <div id="graph">
                        </div>
                        </body>
                        </html>
                        

在文件顶端,为 yearscountries 数组预先加载年份、国家列表及其扫盲值。随后,PHP 需要生成 DHTML 代码的三个区域。第一个填充 JavaScript 中的 years 数组,第二个填充 rates,第三个以国家名设置 <select> 标记的内容。





回页首


散点图

动态创建新 HTML 是 DHTML 的核心。选择之一是构建字符串并在页面上设置元素的内部 HTML。本例给出了第二种方法,使用散点图作为示例。图 3 展示了一个简单等式的散点图。


图 3. 多周期正弦波形图


您可更改等式,并单击 Try It! 按钮更新图形,如图 4 所示。


图 4. 略有差异的等式图形


所有这一切都不必返回 PHP 服务器。本例甚至没有用到服务器 —— 您可以新建一个 HTML 文件,开始编写 HTML 代码。本图的实现代码如清单 3 所示。


清单 3. 散点图代码
<html>
                        <head>
                        <title>Dynamic Graphing Example</title>
                        <style type="text/css">
                        body { font-family: arial, verdana, sans serif; }
                        #graphdiv {
                        height:500px; width:500px;
                        border:1px solid black;
                        position:relative;
                        }
                        </style>
                        <script>
                        function drawgraph()
                        {
                        var g = document.getElementById( "graphdiv" );
                        var eq = document.getElementById( "eq" ).value;
                        var dx = [];
                        var dy = [];
                        var sx = 10000;
                        var ex = -10000;
                        var sy = 10000;
                        var ey = -10000;
                        for( var i = 0; i < 100; i++ )
                        {
                        var x = i / 100;
                        var y = eval( eq );
                        if ( y > ey ) ey = y;
                        if ( y < sy ) sy = y;
                        if ( x > ex ) ex = x;
                        if ( x < sx ) sx = x;
                        dx.push( x );
                        dy.push( y );
                        }
                        var gwidth = 500;
                        var gheight = 500;
                        var imgwidth = 100;
                        var imgheight = 100;
                        var fx = (gwidth-(imgwidth/2))/(ex-sx);
                        var fy = ((gheight-(imgheight/2))/2)/(ey-sy);
                        g.innerHTML = "";
                        for( i = 0; i < dx.length; i++ )
                        {
                        var x = ( dx[i] * fx );
                        var y = ((gheight-(imgheight/2))/2)+(dy[i]*fy);
                        var img = document.createElement( "img" );
                        img.src = "ball.gif";
                        img.style.position = "absolute";
                        img.style.top = y+"px";
                        img.style.left = x+"px";
                        g.appendChild( img );
                        }
                        }
                        </script>
                        </head>
                        <body onload="drawgraph()">
                        Equation:
                        <input type="text" id="eq" value="Math.sin(x*32)" />
                        <button onclick="drawgraph()">Try It!</button>
                        <br/><br/>
                        <div id="graphdiv">
                        </div>
                        </body>
                        </html>
                        

本例的大部分代码都位于 JavaScript 函数 drawgraph 中。该函数创建两个数字数组 —— 一个存储 x 值,另外一个存储 y 值。x 轴的数字范围为 0 到 1,y 轴的数字是通过将各 x 值代入等式计算得出的。

数据通过等式生成,但代码为各轴设置了最小值和最大值,并按此自动调整数据。

将图像置入图形需要用到一种新技术:我们使用 document.createElement 来构建一个 <img> 标记,随后使用 appendChild 将新创建的 img 对象添加到图形对象中。这项技术要优于使用字符串设置 innerHTML,因为代码更易于阅读和维护 —— 而且您不必担心字符串编码问题。

使用 createElement 的技术符合 World Wide Web Consortium(W3C)Document Object Model(DOM)规范,也是动态创建 HTML 元素的首选方法。





回页首


散点图的 PHP 代码

散点图示例自成体系。PHP 代码将散点图打包为组件。该组件的代码如清单 4 所示。


清单 4. 散点图的 PHP 代码
<?php
                        function graph_header()
                        {
                        ?>
                        <style type="text/css">
                        body { font-family: arial, verdana, sans serif; }
                        #graphdiv {
                        height:500px; width:500px;
                        border:1px solid black;
                        position:relative;
                        }
                        </style>
                        <script>
                        function drawgraph()
                        {
                        var g = document.getElementById( "graphdiv" );
                        var eq = document.getElementById( "eq" ).value;
                        var dx = [];
                        var dy = [];
                        var sx = 10000;
                        var ex = -10000;
                        var sy = 10000;
                        var ey = -10000;
                        for( var i = 0; i < 100; i++ )
                        {
                        var x = i / 100;
                        var y = eval( eq );
                        if ( y > ey ) ey = y;
                        if ( y < sy ) sy = y;
                        if ( x > ex ) ex = x;
                        if ( x < sx ) sx = x;
                        dx.push( x );
                        dy.push( y );
                        }
                        var gwidth = 500;
                        var gheight = 500;
                        var imgwidth = 100;
                        var imgheight = 100;
                        var fx = (gwidth-(imgwidth/2))/(ex-sx);
                        var fy = ((gheight- (imgheight/2))/2)/(ey-sy);
                        g.innerHTML = "";
                        for( i = 0; i < dx.length; i++ )
                        {
                        var x = ( dx[i] * fx );
                        var y = ((gheight-(imgheight/2))/2)+(dy[i]*fy);
                        var img = document.createElement( "img" );
                        img.src = "ball.gif";
                        img.style.position = "absolute";
                        img.style.top = y+"px";
                        img.style.left = x+"px";
                        g.appendChild( img );
                        }
                        }
                        </script>
                        <?php
                        }
                        function graph_place()
                        {
                        ?>
                        </head>
                        <div id="graphdiv">
                        </div>
                        <?php
                        }
                        ?>
                        

此代码定义了两个函数:graph_headergraph_placegraph_header 函数应在文档的开头部分调用,graph_place 则应在您需要加入图形的地方调用。清单 5 展示了更新的图形页面代码。


清单 5. 更新的散点图 PHP 代码
<?php
                        require_once( "graph_component.php" );
                        ?>
                        <html>
                        <head>
                        <title>Dynamic Graphing Example</title>
                        <?php graph_header(); ?>
                        </head>
                        <body onload="drawgraph()">
                        Equation:
                        <input type="text" id="eq" value="Math.sin(x*32)" />
                        <button onclick="drawgraph()">Try It!</button>
                        <br/><br/>
                        <?php graph_place(); ?>
                        </body>
                        </html>
                        

这比原始页面要简单得多。首先将组件代码包含进来。随后调用 graph_header 来添加 JavaScript 和 CSS。最后在希望将图形放置在页面上的地方调用了 graph_place 函数。





回页首


DHTML 能走多远?

JavaScript 代码的强大与简单非常吸引人。但问题很快发生了变化,不再是插入的代码有多么少,而是革新的路能走多远。Google Maps(参见 参考资料)是 DHTML 应用程序的典范,它证明了 DHTML 应用程序不仅在站点上有用,而且可集成到任何 Web 页面上 —— 只需编写一些简单的 JavaScript。但 Google 并没有就此止步:它又创建了 Gmail(参见 参考资料),将 DHTML 的应用扩展到创建易于使用的邮件客户端 —— 就在浏览器中。(或许您的 JavaScript 无法成就至此,但如果您确实投入时间去努力,也会欣喜地发现能取得怎样的成果。)

每一名 DHTML 程序员都应该钻研的一项技术就是 Asynchronous JavaScript and XML(Ajax)。Ajax 为浏览器带来了后台处理 Web 请求的能力。这意味着,您的 DHTML 应用程序可回调到 PHP 应用程序,而不需刷新页面。随后页面可使用那些数据刷新所显示的信息 —— 完全不会使浏览页面的用户感觉不快。(关于 Ajax 文章与教程的相关信息,请参见 参考资料 部分。)





回页首


结束语

使用 PHP 和 DHTML 设计 Web 2.0 应用程序” 系列的上一篇文章从新的时髦词 Web 2.0 展开讨论。而业界的另一重要时髦词就是富客户机应用程序。两者同样意味着极酷的 Web 应用程序,您可以同样的方式看待它们。大量技术日益涌现,目标都是创建功能丰富的 Internet 应用程序。Laszlo 和 MXML 大大简化了 Flash 的构建,Microsoft? 的 Vista 也引入了一些新理念。但就构建功能丰富的 Internet 应用程序而言,DHTML 依然是最有诱惑力的,原因就在于您可以使用 PHP 这样的现有技术来完成这一使命。

本文示范了通过简单的 CSS 和 JavaScript 丰富客户体验的几种方法。您可以在现有 Web 应用程序中实现同样的目标 —— 立即开始一个 <script> 标记,享受乐趣吧。





回页首


参考资料

学习

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


讨论




回页首


关于作者

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






回页首

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
移动端HTML5实现文件上传功能【附代码】
不用插件实现WordPress代码高亮显示
JS大幅卷屏广告代码
js常用基础案例整理(持续更新)
HTML链接代码
经验分享:10个简单实用的 jQuery 代码片段
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服