外部链接文字:10分
标题:10分
域名:7分
H1,H2字号标题:5分
每段首句:5分
路径或文件名:4分
相似度(关键词堆积):4分
每句开头:1.5分
加粗或斜体:1分
文本用法:1分
title属性:1分
alt标记:0.5分
Meta描述(Description):0.5分
Meta关键词(Keywords):0.05分
设置Apache虚拟目录
httpd.conf文件中加一行
Alias /vd "d:/vd/"
表示将d:/vd/目录设置为虚拟目录/vd/,那么你在d:/vd/下的文件,就可以通过在浏览器中输入“http://127.0.0.1/vd”访问。
注:当然你可以写成
Alias /vd/ "d:/vd/"
但是这样的话,你要输入http://127.0.0.1/vd/才能访问,而上面那种只要http://127.0.0.1/vd

2000/XP/2003 下 IIS+PHP+MySQL+Zend Optimizer+GD库+phpMyAdmin安装配置
(假设 C:\ 为你现在所使用操作系统的系统盘,如果你目前操作系统不是安装在 C:\ ,请自行修改。)
一、安装 IIS(Windows2003只要安装“应用程序服务器(IIS,ASP.NET)”即可跳过此步):
(1)插入系统盘;
(2)进入控制面板-》添加或删除程序-》添加/删除Windows组件-》在“Internet信息服务(IIS)打勾-》下一步安装。
(3)安装完成后在浏览器地址栏输入 htt://127.0.0.1 检查是否安装正常。
如果没有系统盘,那么下载 IIS 5.1 的安装包(for XP),重复上述步骤,安装时指定路径即可。
IIS下载地址:http://soft.mumayi.net/downinfo/2597.html
二、安装 PHP:
(1)官方下载:http://www.php.net/downloads.php。
(2)下载后得到 php 的 zip 压缩包,解压至 C:\php(这个路径可以随意,下面要是用到这个路径,请相应修改);
(3)将 C:\php\libmysql.dll 和 C:\php\ext\php_mysql.dll 复制到 C:\Windows\system32 下;
将 C:\php\php.ini-recommended 复制到 C:\Windows (Windows 2000 下为 C:\WINNT)并将改名为php.ini,
然后用记事本打开,利用记事本的查找功能搜索:
搜索“; Windows Extensions”并仅打开需要的模块以节省内存(去掉每个模块前的;号即可):
extension=php_gd2.dll
GD库支持,支持水印。
extension=php_mbstring.dll
支持phpMyAdmin
extension=php_mysql.dll
支持MySQL。
(4)配置 IIS 使其支持 PHP
在“控制面板”的“管理工具”中选择“Internet 服务管理器”,
然后在左侧选择你需要支持 PHP 的 Web 站点上单击右键选择“属性”,
在打开的“Web 站点属性”窗口的“ISAPI 筛选器”标签里找到并点击“添加”按钮,在弹出的“筛选器属性”窗口中的“筛选器名称”栏中输入:PHP,再将可执行文件指向 php5isapi.dll 所在路径,如:C:\php\php5isapi.dll。
打开“Web 站点属性”窗口的“主目录”标签,找到并点击“配置”按钮,在弹出的“应用程序配置”窗口中找到并点击“添加”按钮,在弹出的窗口中新增一个扩展名映射,扩展名为 .php ,单击“浏览”将可执行文件指向 php5isapi.dll 所在路径,如:C:\php\php5isapi.dll,然后一路确定即可。
再打开“Web 站点属性”窗口的“文档”标签,找到并点击“添加”按钮,向默认的 Web 站点启动文档列表中添加 index.php 项。您可以将 index.php 升到最高优先级,这样,访问站点时就会首先自动寻找并打开 index.php 文档。
确定 Web 目录的应用程序设置和执行许可中选择为纯脚本,然后关闭 Internet 信息服务管理器。
2003系统配置:在“Internet 服务管理器”左边的“WEB服务扩展”中设置:
ISAPI 扩展允许
开始-》运行-》输入“iisreset”,重启IIS。
在 IIS 根目录下新建一个 phpinfo.php,内容如下:
<?php
phpinfo();
?>
打开浏览器,输入:http://127.0.0.1/phpinfo.php,将显示当前服务器所支持 PHP 的全部信息。
三、安装 MySQL:
(1)官方下载:http://dev.mysql.com/downloads/mysql/5.2.html
custom
安装
Skip Sign-Up
Finish
Next
Standard Comfiguration
设置数据库密码
(重要)重新启动电脑!
四、安装 Zend Optimizer :(有需要时安装)
(1)官方下载:http://www.zend.com/products/zend_optimizer
(2)安装时只需选择Web服务器为iis,指定php.ini路径即可。
五、安装 phpMyAdmin:(用于管理MYSQL数据库,可选择)
下载 http://www.phpmyadmin.net,将其解压到站点根目录,
找到 ./libraties/config.default.php,做以下修改:
方案一:
搜索 $cfg['Servers'][$i]['auth_type'] 设置为config
搜索 $cfg['Servers'][$i]['user'] 用户名一般为root
搜索 $cfg['Servers'][$i]['password'] 设置MySQL的密码
打开浏览器,输入:http://127.0.0.1/phpMyAdmin/ ,若 IIS 和 MySQL 均已启动,即可浏览数据库内容。
(此设置允许任何人通过以上路径登录管理数据库,安全性极低)
方案二:
搜索 $cfg['Servers'][$i]['auth_type'] 设置为cookie
搜索 $cfg['Servers'][$i]['user'] 用户名一般为root
搜索 $cfg['PmaAbsoluteUri'] 访问路径,设置为http://127.0.0.1/phpmyadmin/
搜索 $cfg['blowfish_secret'] 这是cookie作用域,设置为127.0.0.1
(此设置只允许本机上登录,并且需要输入用户名密码才能登录,安全性极高)
-----------------------------------------------------------------------------------
至此所有安装完毕。以上配置在所有老版本软件中不一定有效,强烈推荐下载最新版本的软件。

简单安装过程:请各位注意安装顺序
----------------------------------------------------
(一)Apache:
装在默认目录。安装-自定义-全部选中。
----------------------------------------------------
(二)PHP:
第一步:压缩C:\php5目录下。
第二步:(将PHP目录添加到PATH环境变量中)开始 -> 控制面板 -> 系统 -> 高级 -> 环境变量 -> 系统变量 -> Path -> 双击 -> 加入“;C:\php5”
第三步:将C:\php5\php.ini-recommended 重命名为 php.ini 。
用记事本打开 php.ini ,查找register_globals = Off,把off改成On (有二处)
查找short_open_tag = Off,把off改成On 有一处
查找extension_dir = "./" 改为 extension_dir = "C:\php5\ext"
查找;extension=php_mbstring.dll,把下面几句前面的分号去掉
extension=php_mbstring.dll
extension=php_dba.dll
extension=php_dbase.dll
extension=php_filepro.dll
extension=php_gd2.dll
extension=php_imap.dll
extension=php_ldap.dll
extension=php_mysql.dll
修改了一些文件上传以及内存使用最大限制:
memory_limit = 20M 内存容量
post_max_size = 20M 闪存容量
upload_max_filesize = 20M 附件容量
保存退出。
第四步:(使php.ini文件在Windows下被PHP所用)
开始 -> 控制面板 -> 系统 -> 高级 -> 环境变量 -> 系统变量 -> 新建 -> 输入“PHPRC” -> 在“变量值”中输入 php.ini文件所在的目录(例如:C:\php5)
点击“确定”
Microsoft Windows 下的 Apache 2.0.x
先停止Apache
用记事本打开C:\Apache2\conf(可能在C:\Program Files\Apache Group\Apache2\conf)下的httpd.conf
这个文件我改了几个地方:
把PHP直接作为apache的一个模块运行,我在里面加了两句:
查找到 #LoadModule ssl_module modules/mod_ssl.so 在它的下面一行加上
LoadModule php5_module "C:/PHP5/php5apache2.dll"
AddType application/x-httpd-php .php 注意点前面有个空格滴,大家最好用复制粘贴
(新版apache2.2的php5apache2_2.dll在外面,放上去同理用)
我在D盘下建立了一个www的目录用于存放我的站点文件,在http.conf里改了这样一句话:
把
DocumentRoot "C:/Program Files/Apache Group/Apache2/htdocs"
改成了
DocumentRoot "D:/www"
所有
Apache2.0.x于1.3.x相比2.0.x默认不能直接列目录,如需,就改:
把DocumentRoot "E:/www"这句下的如下语句
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
改为:
<Directory />
Options Indexes FollowSymLinks
AllowOverride None
</Directory>
修改目录的默认首页:
如:DirectoryIndex index.htm index.html index.php index.html index.html.var
别的就没再动什么地方,保存后退出。
注意一点的是,要使以上所有这些配置生效需要重新启动电脑
最后我们来测试PHP是否正常载入。打开记事本,输入
<?php
phpinfo();
?>
保存,在弹出的窗口中,文件类型选所有文件,文件名为phpinfo.php,保存位置为网站目录下。如(E:\www\phpinfo.php)
打开IE浏览器输入:http://localhost/phpinfo.php 如果能正常显示就OK了。
-------------------------------------------------------
(三)Zend:
先停止Apache
安装Zend Optimizer也很简单,安装中它会两处提示其一:选择那种服务器?请选择Apache。其二:PHP.ini的路径?请选择C:\PHP5。其它的按默认配置安装就行了。OK安装完后我的Zend目录就是C:\Zend。
-------------------------------------------------------
(四)Mysql:

部署Silverlight到产品Web服务器是一个相当容易的过程,尽管有时候会有一些错觉——譬如,认为Silverlight需要部署在基于微软的Web服务器(IIS)上,事实上, Silverlight不强制一定部署在基于微软的Web服务器上,Apache也可以像IIS一样,轻松愉快的支持Silverlight运行。
但是还是要那么一点东东要指出来:Web服务器通常都只支持有限种已知扩展名的静态文件内容。看起来都很好,但是Silverlight引入了两个新的文件扩展(.xaml为松散XAML文件;.xap为基于zip压缩的二进制包格式文件),因此,你需要为web服务器添加MIME类型,这样才能让Web服务器识别并处理那些类型的文件。下面列出了你需要添加到Web服务器的MIME类型:
Extension | MIME Type |
.xaml | application/xaml+xml |
.xap | application/x-silverlight-app |
这些就是你所有需要做的。但是具体到如何为不同的web服务器添加MIME类型,实际因web服务的不同而不同,下面列出了目前流行的一些web服务器和他们的链接,你可以从哪里找到如何配置和更多的信息:
当你在更新所支持的MIME类型的时候,或许还想添加相关的类型,如WPF和ClickOne应用程序的支持,那么还需要添加下表中的MIME类型:
Extension | MIME Type |
.manifest | application/manifest |
.application | application/x-ms-application |
.xbap | application/x-ms-xbap |
.deploy | application/octet-stream |
.xps | application/vnd.ms-xpsdocument |
但是如果你的web服务器在一个你不能修改其配置的共享的服务器上,那么你可以通过修改XAP文件成web服务器已支持的MIME类型来“欺骗”服务器,从而支持xap文件。XAP文件实际上是基于zip压缩的,所以可以直接把.XAP给成.ZIP,并在HTML中把Silverlight对象的source参数指到新的文件目录即可。这里有一个示例(点击这里查看),通过查看网页源代码你可以看到这项技术的实质——它就是指向一个zip压缩文件(里面包含Silverlight内容的)的纯HTML页面。
最后有一个好消息是,随Windows Server 2008发布的IIS 7.0默认已经支持了以上的WPF和Silverlight的MIME类型,包括.xap和.xaml类型扩展。所以如果你使用Windows Server 2008,就已经万事大全,只欠东风了。(另外,对于Vista,不论是全新的安装Vista SP1还是从Vista SP1 RTM升级到SP1 Release,你的IIS的配置只有在先卸载IIS功能在重新安装IIS才会更新。)
【原文地址】First Look at Using Expression Blend with Silverlight 2
【原文发表日期】 Thursday, February 28, 2008 9:36 PM
上个星期,我写了一个《Silverlight 2 初览》的贴子,讨论即将发布的Silverlight 2 Beta1 版。在该贴子里,我给出了一些我撰写的系列教程的链接,这些教程示范了Silverlight和WPF后面的一些根本性编程概念,以及演示如何使用它们来建造一个Silverlight版的“Digg搜索客户端”应用:
在这第一套Silverlight教程里,我没有使用可视化的设计工具来建造用户界面,而是注重于展示底层的XAML UI标识(我认为这有助于更好地解释核心编程概念)。既然我们完成了对基本概念的讨论,让我们来探究一下可为我们所用,变得更有效率的一些工具。
Expression Blend对Silverlight的支持
除了即将发布Silverlight 2的Beta1版本外,我们还将发布针对这个版本的Visual Studio 2008 和 Expression Studio 的工具支持。这些工具将为建造RIA应用提供强有力的支持,是设计来允许开发人员和设计师轻松地合作开发项目的。
在今天的贴子里,我将介绍即将发布的Expression Blend 2.5三月份预览版的一些功能。在演示关于Blend是如何工作的一些基础的东西之后,我们将用它来建造一个跨平台,跨浏览器的 Silverlight IM聊天客户端:
上面的屏幕截图展示了在MAC上运行时该应用的样子,下面是在Expression Blend中该应用设计时的屏幕截图:
我们将使用Expression Blend,用可视化方法构造该应用所有的用户界面,以及使用它来干净地将UI数据绑定到代表我们的聊天会话和消息的.NET类上。
我们用来建造聊天应用的所有控件都是Silverlight 2的Beta1版的一部分。
声明:我不是设计师(也不很酷)
让我预先声明,我是个开发人员,不是个设计师。我也不是很酷。虽然我理解创建用户界面的技术,但在组合界面时,我有时会挑选很差的颜色和字体(就在我弄完本贴的屏幕截图之后,有个同事十分有助地指出,实际上有个致力于取缔我使用的一些字体和颜色的专门网站,哎,很受打击)。
我想对你们中那些有艺术细胞的人说,请对我温柔点,将你的注意力集中在我在下面演示的功能和技术上,别针对我使用的字体和颜色选择, :-)
起步: 创建一个新Silverlight 2项目
Expression Blend 和 Visual Studio 2008共享同样的解决方案/项目文件格式,这意味着你可以在VS 2008中创建新的Silverlight 项目,然后在Expression Blend 中打开,或者你也可以在Expression Blend 创建新的Silverlight 项目,然后在VS中打开。你还可以使用Expression Blend和VS 2008同时打开和编辑同个项目。
因为在我先前的Silverlight教程系列中,我已经展示了如何使用VS 2008来创建一个新Silverlight项目,让我们用这个贴子来展示如何使用Expression Blend来创建一个新的Silverlight应用。要做的话,只要在Expression Blend中选择 文件->新项目 ,选择Silverlight 2 Application图案,然后点击OK:
这会创建一个新的(与VS相兼容的)解决方案文件和Silverlight应用项目:
Blend包括了一个面向Silverlight 2应用的完整的所见即所得的设计器。在打开Silverlight页面和控件时,你可以在设计视图,XAML源码视图,或者同时显示设计视图和XAML源码视图的分割视图之间转换设计表面(支持同步编辑)。在上面我们使用了分割视图这个选项。
理解一些基本的东西:往表面上加控件
Expression Blend拥有一个与Visual Studio稍微不同的工具调色板(tool palette)(与你在像Photoshop这样的设计工具里的找到的调色板更相似些)。
Blend支持矢量图像编辑:
Blend还支持添加和操作控件。在放置布局控件(Grid, Stack, Canvas, Border, ScrollViewer等),文本控件(TextBox, TextBlock等)的工具箱中,有个特殊的图案,以及一个显示你最近用过的控件的图案:
点击工具调色板上最后面的">>"图案会显示可为你所用的所有的控件:
确认点击了Asset Library的右上角的“Show All(显示所有控件)”的复选框,如果你看不到你在找的控件的话。你还可以使用“搜索”文本框,来按名称过滤所显示的控件。
重要注意事项: Blend对所有控件都支持一种设计体验(无论是内置的控件还是第三方的控件或你应用引用的用户控件)。
在你从工具箱里选中一个控件后,你可以在设计表面点击,拖拉,画出控件来。你也可以把控件从asset工具拖拉到artboard上。在默认情形下,当你在设计表面上添加控件,与之交互时,你将得到自动的尺子和定位标记 (下面是一个带有内置按钮,日历和slider控件的表单):
理解其他基本的东西:操作控件属性
你可以在设计表面上选择任何对象,然后在屏幕的右手边点击“属性”面板,来定制它的属性:
在上面,我在把按钮的“背景”画刷改成渐变的深蓝(deeper blue gradient)(在“Brushes(画刷)”节点下面用红笔圈中的第三片,它允许我们配置渐变式的画刷)。
有用的小技巧: 属性窗口的上方包含一个搜索框,你可以用它来过滤可见的属性名称:
因为Silverlight和WPF中所有的UI对象都是使用矢量图像组成的,我们可以任何方式对控件进行变形,样式化,转换。例如,我们可以设置我们的按钮控件的Transform属性或者点击它的边角来旋转,倾斜,扩缩它:
这给与我们很大的威力和灵活性,来快速和轻松地定制我们想要的体验:
有用的小技巧: 你可以按住CTRL键来放大或缩小设计表面,然后使用你的鼠标的滑轮来控制放缩的深度。然后你可以通过按住空格键来移动设计表面的可见区域,这会导致手形光标的显示,然后你可以按住鼠标,用它来把当前可见的区域在屏幕上拖拉。后面这个小技巧在你放大得太多,想轻松地移动可见内容时会非常有用。
建造我们的聊天应用: 定义布局
在我先前的Silverlight教程系列中的第二部分:使用布局管理 (木野狐译)中,我曾谈到Silverlight和WPF中的布局管理系统,以及如何使用布局面板来轻松地控制应用的布局和流程。Expression Blend可以使得定义布局规则变得容易,还包括使用这些布局面板的内置工具支持。
记住,我们建造聊天应用的目标是拥有象这样的UI:
要达成这个目标,我们先在网页上定义三行的<grid>布局,我们可以这么做,把鼠标悬浮在设计表面的左边缘,然后点击我们想生成新的行定义的地方(在下图中,我已经建立了顶行的定义,用红笔圈出的光标所在表示我将点击来添加第二行定义的地方):
点击设计表面的左上角(下图红圈处)允许我们转换设计表面是处于 Canvas 布局模式还是Grid布局模式:
在Grid布局模式中时,Blend 会告诉我们某个行或某个列是否有固定的宽度,或是否与控件的尺寸成比例关系。上面的“空锁(empty locks)”表示这三行之间目前成比例关系(意味着它们会按比较增加,如果我们加大浏览器的大小的话):
如果我们点击顶部和底部的锁的话,我们可以把这些行设置成拥有固定的高度,而让中间一行填充剩下的高度:
我们要做的最后一步是点击顶部的边缘,再定义一个右手的列,我们将其设置成拥有固定的宽度(让左边那列动态地改变大小):
在做完上面的步骤之后,我们的XAML文件将有一个定义成下面这样的Grid:
有用的小技巧: 在上面,我们对我们的Silverlight应用设置了固定的宽度和高度(注意<UserControl>根元素上的Width 和 Height属性)。我们也可以完全去掉Width和Height属性,致使应用拥有动态的大小,自动地流式改变大小来适合包含它的HTML元素或浏览器窗口的大小。(我曾在这里的教程的结尾谈到过这个技巧)。如果我们要给我们的应用设置设计时的宽度和高度,我们可以在根UserControl元素上设置 d:DesignWidth="640" 和 d:DesignHeight="476" 属性。这会在使用设计器来设计应用时,致使设计器使用该尺寸的大小。
建造我们的聊天应用: 添加控件和颜色
至此,我们定义了我们的聊天应用的核心布局,让我们往里面加些控件,开始定制它的外观。
我们将先选择根Grid布局面板,定制它的背景颜色为渐变的蓝色(blue gradient)。可为我们所用,选择一个特定控件的一个简单的方法是使用“Interaction(交互)”面板,然后点击我们想选择的控件:
然后我们可以使用“"Brushes(画刷)”属性面板来定制一个蓝色的 LinearGradient 画刷为Grid的背景:
设置完成后,我们可以开始操作聊天窗口的底部,加一个“Send”(发送)按钮:
至于我们的聊天消息文本框,我们则将使用一个标准的文本框。但要加点活力,我们将先加一个RoundRadius为5的边框控件,然后加象这样的Background(背景)和BorderBrush(边框画刷):
然后我们在Border控件中嵌入我们的TextBox。
重要的小技巧: 为使用设计表面把TextBox嵌套在Border控件之中,我们需要在Interaction窗口中双击Border控件。这会将其设置成设计表面上的当前可插入控件,象下面这样用黄色高亮显示:
然后我们可以使用控件工具箱选择一个TextBox控件,将其加进Border控件。我们将设置TextBox的背景和边框画刷从父控件Border处继承其好看的曲线型外观:
Blend生成的XAML标识看上去象这样(注意,TextBox是内嵌在Border控件之中的,如果Border不是当前插入控件的话,是不会这样的):
我们也可以对header行重复上面的过程,将一个TextBox嵌入一个Border控件中,在右列里加一个图片控件,创建出象这样的UI:
由Blend生成的XAML标识会看上去象下面这样:
最后,绝对不是最不重要,我们将在中间一行添加另一个Border控件,往其中加一个ListBox控件。我们将配置Border控件延伸跨越Grid的两列,将它的背景和前景颜色进行定制。然后我们在ListBox加一些测试消息作为站位文字(我们将在后面对UI进行定制,并将其绑定到实际数值):
由Blend生成的XAML标识将看上去象下面这样:
至此,我们运行应用的话,我们会有一个在浏览器中运行的基本的聊天IM客户端(带硬写的值)。在我们改变浏览器大小时,应用会自动流动,改变大小以适合窗口:
我们还有一堆UI活要干,使我们的IM客户端看上去不至于很粗糙,但至少我们现在有东西可以运行了。
建造我们的聊天应用: 添加ChatMessage和ChatSession 2个类
至此,我们在Expression Blend中创建了初始的UI,让我们在 Visual Studio 中打开同个项目,加些我们可以绑定到UI的一些聊天类。
我们可以在 Visual Studio中选择 VS 2008 中的文件->打开项目,然后选择我们项目的项目文件来打开项目,或者在Expression Blend中我们可以右击项目节点,然后选“Edit in Visual Studio(在Visual Studio中编辑)”菜单项来启动打开了项目的VS 2008:
Beta1版本中的VS 2008的Silvelight支持包括对Silverlight 2方案的项目管理支持,完整的Intellisense和事件连接支持,以及对在Windows和Mac上运行的Silverlight应用的调试支持。VS 2008还支持对Silverlight .xaml文件的分割视图的编辑。譬如,下面是我们在Blend 建造的同个Page.xaml 文件,在VS2008中打开后的样子:
Beta1版的VS 2008设计视图并不是可交互的(意味着还是只读)。但你在源码视图中做的变动会马上在设计视图中更新,这给予你一个很好的XAML-pad的体验(在Silverlight 2 Beta1中,VS 2008支持完整的XAML源码intellisense)。
在这个博客贴子里,我们不会使用Visual Studio的XAML编辑器,而是将创建一些类,我们可以用来代表ChatSession以及相关的聊天消息。然后我们将使用Expression Blend将我们的UI控件绑定到这些类上。
我们先加一个定义了2个公开属性的叫“ChatMessage”的新类:
然后我们将创建一个叫“ChatSession”的类,它代表了一个聊天会话:
上面的ChatSession类有三个公开的属性,前2个属性代表远程聊天对象的用户名和avatar。
第三个属性是过去聊天消息的集合。注意,它的类型不是List<ChatMessage>集合,而是一个ObservableCollection<ChatMessage>集合。ObservableCollection对你来说,也许是个不熟悉的类型,假如你来自ASP.NET背景的话,但对那些来自Windows Forms或WPF背景的,大概会非常熟悉。基本上来说,这是个泛型集合类,往其中添加或去除条目时(或者其中的条目实现了INotifyPropertyChanged的话,在属性变动时),它会发出变化通知事件。这在做数据绑定时会非常方便,因为UI控件可以使用这些通知来知道自动刷新它们的值,而不用开发人员编写代码来显式地这么做。
ChatSession 还有2个公开的方法,其中一个方法的任务是连接到聊天服务器上去,另一个方法的任务是向聊天服务器发送消息。为简单起见(也因为我没有聊天服务器),我会对2个方法做假的实现。在实战中,我们大概会使用内置于Silverlight的网络socket实现连接到一个远程的聊天服务器上去。
ChatSession类实现了INotifyPropertyChanged接口,意味着它会呈示一个公开的PropertyChanged事件。在这个类中,我们会在改变它的属性时,触发这个事件。这会在属性值发生变化时,通知监听者(例如,与它数据绑定的控件),以允许它们重新绑定数据。
为设计时数据绑定实现假的数据
从纯粹功能性的角度来说,上面的代码是为实现我们的聊天客户端所需的所有的代码。但为帮着改进在Blend中的设计时体验,我们还将加一个构造器,检查我们是处于运行时模式还是设计模式,如果宿主于设计器里,那么就给ChatSession装载假的数据:
一会儿我们就会看到这是如何方便在设计器里呈现数据绑定之数据的。
建造我们的聊天应用: 在Expression Blend中使用数据绑定连接UI
既然我们定义了ChatMessage和ChatSession对象,我们可以在Expression Blend 中用它们来绑定到我们的UI控件了。
在我上个星期的《教程第五部分:用 ListBox 和 DataBinding 显示列表数据》 (木野狐译)中,我介绍了Silverlight和WPF中数据绑定的工作原理。在今天的贴子里,我们将使用Expression Blend 来连接数据绑定表达式,而不是手工输入这些表达式。我们将先使用Blend中Project面板下的"Data"面板:
我们将点击Data面板中的“+ CLR Object”链接,调出一个对话框,允许我们挑选任何.NET对象来数据绑定到我们的UI控件。我们将用它来选择我们刚创建的“ChatSession”对象:
这会把ChatSession对象加到我们的Data托盘上去,将它的属性(以及子属性)显示在一个树形视图里:
然后我们就可以在设计视图里通过选择Data托盘里的这些属性,把它们拖放到设计表面上的UI控件上,来绑定任意一个UI控件到这些属性上。例如,我们可以把RemoteUserName属性从Data托盘上拖拉到静态的"ScottGu"标签上,将它换成{Binding RemoteUserName} 数据绑定表达式:
当我们把“RemoteUserName”属性拖放到TextBlock上时,Blend会象上面那样问我们,是绑定这个属性到现有的TextBlock,还是创建一个新的控件来代表这个属性。如果我们选择默认的行为(绑定到现有的控件上),Blend就会询问我们想要的绑定表达式的类型:
我们表明我们要“OneWay(单程)”绑定到TextBlock的“Text”属性上去。当我们点击OK时,我们的控件的“Text”属性就会被更新为 {Binding RemoteUserName} 表达式。
我们可以重复这个拖放交互过程,把Image控件绑定到RemoteAvatarUrl 属性,也把 ListBox 绑定到MessageHistory集合属性上。完成之后,Blend就会象下面这样在设计视图表面中显示我们的伪数据:
你也许会对ListBox的内容感到疑惑,为什么条目都显示成了“ChatClient.ChatMessage”?那个么,目前ListBox是绑定到了自定义的.NET 对象的集合,“ChatClient.ChatMessage”字符串是调用ChatMessage实例的“ToString()”方法返回的值。
我们可以象这样,加一个<DataTemplate>到ListBox来修改它,让它好看些:
注: 在Blend 2.5 三月份的预览版中,你只能在源码视图中定义数据模板。在将来的预览版中,你将能够使用设计器来定义它们。这个功能已经在WPF中实现,如果你想试验一下的话。作为一个设计师,你可以交互式地创建数据的外观,完全的所见即所得的体验。去创建一个WPF项目试一下。
这么做的结果,会使得我们的UI在设计时看起来象下面这样:
在设计时显示这些“伪数据”的好处是,它允许我们对在运行时UI体验是什么样的会有一个比较好的感觉,允许设计师(或开发人员)轻松地设计UI,而不需要等待应用的其他部分的完成。
建造我们的聊天应用: 使用样式和控件模板更新我们的Button和ListBox的UI
在我的《第七部分:使用控件模板定制控件的观感 》Digg教程中谈到的一件事情是,关于Silverlight和WPF如何允许开发人员和设计师完全定制控件的观感(look and feel )的。这提供了巨大的灵活性来精雕细琢应用的UI,以创建恰如其愿的用户体验。
我们可以使用Silverlight和WPF的控件模板特性来定制我们上面聊天应用的Send按钮和ListBox结构,以构造稍微好看的观感。我们可以这么做,创建 "MessageHistory" 和 "SendButton" 样式资源,将之保存在项目的App.xaml文件中。每个样式对象可以有一个控件模板,修改了控件的观感和改变它的视觉结构。
注: 在Blend 2.5 三月份的预览版中,你只能在源码视图中定义数据模板。在将来的预览版中,你将能够使用设计器来定义它们。这个功能已经在WPF中实现,如果你想试验一下的话。作为一个设计师,你可以交互式地创建数据的外观,完全的所见即所得的体验。去创建一个WPF项目试一下。
例如,下面的ListBox控件模板可以用来去除ListBox控件周围的外圈双边框,定义一个只有列表容器卷动条的“平(flat)”的外观:
将这个模板施用到我们的ListBox上,将使得它显示出边缘周围平滑很多的样子:
我们可以用我们按钮的控件模板做得很花哨些,不光是定义一个自定义的按钮形状,还可以定义各种故事板动画来用于该形状,在它处于"MouseOver(悬浮)", "Pressed(按下)", 或"Normal(正常)"状态时, 提供自定义的UI行为(所有这些东西都可以封装在Style定义之中,意味着页面的开发人员不用做什么就可以启用这些东西):
在定义了"MessageHistory" 和"SendButton" 样式对象之后,很容易使用Expression Blend 将它们施用到设计表面的控件之上。
点击Expression Blend中的“Resources”工具窗口,它会列出我们项目中的所有资源地点:
我们可以展开“App.xaml”节点看其中我们可以使用的样式。要将一个特定样式施用到页面上的某个控件,我们只要将它拖放到该控件上就可以了。例如,这是在我们施用“SendButton”样式之前我们的发送按钮控件的样子:
将SendButton样式拖放到它之上,会将它改成使用我们自定义的控件模板形状/结构
因为我们的“SendButton”样式中定义了状态动画效果,按钮在运行时会随终端用户与之交互的方式的不同而变化。
在默认情形下,按钮看上去象这样:
当终端用户将鼠标移到按钮之上时,气球会微妙地变到比较淡的颜色:
在处于按下的状态时,按钮会陷下去,它的影子会消失:
在释放时,按钮又会冒起来。
这些微妙的动画和交互性姿态可以给应用增添一些色彩。最棒的是,设计师可以完全由他们自己建造和定制这些功能,实现页面功能的开发人员根本不用参与也不用编写任何代码,就可以启用这些功能。
在Expression Blend 2.5的将来的预览版中,设计师将不光能定义这个按钮的形状和结构,还能为它定义所有的动画过渡,全部使用设计表面(不需要编辑源码,也不用任何代码)。
实现我们的聊天功能
至此,我们使用Expression Blend对我们的控件UI做了数据绑定,还对UI的交互性做了修改和润色,让我们回到Visual Studio,来编写实现UI聊天行为功能的代码。
特别地,我们将向我们Page的构造器里添加下列代码,来开始与一个远程用户的ChatSession,然后处理“Send”按钮被点击,给远程用户发送一个消息时的场景:
在添加完上面的代码之后,重新运行我们的应用,我们将看到我们的UI现在数据绑定到了一个与RemoteUserName为"ScottGu" 的ChatSession(聊天会话),而不是我们早先定义的假的设计时数据。在消息文本框里输入文字,点击定制的Send按钮时,我们的ListBox会自动显示更新过的聊天历史:
你也许在疑惑为什么ListBox会自动更新?它这么做的原因是因为ListBox是数据绑定到ChatSession.MessageHistory属性上的,该属性的类型是ObservableCollection<ChatMessage>。这意味着,在一个新的 ChatMessage 对象添加进来时,该集合会自动触发变化通知事件,ListBox就会监测到这个事件,然后就会用新的数据更新本身。
不需要我们编写代码,就可以让ListBox对这些变化做反应。我们应用的干净的视图/模型绑定架构会自动为我们做处理。
结语
我只展示了Expression Blend支持的几个特性而已,所有这些特性在Silverlight和WPF项目中都工作的。所有这些功能都将在即将发布的Expression Blend 2.5三月份预览版中发布,不久这个预览版就可(免费)下载。
我想你会发现Visual Studio 2008 和 Expression Studio 会给建造出色的RIA解决方案带来巨大的生产力和威力。开发人员和设计师可以在开发相同项目时协作使用它们(而不用相互妨碍对方)。你还可以轻松地在一个机器上同时打开它们,用它们来同时编辑同一个应用。
在Expression Blend可以下载之后,我将在博客中对它做更多的讨论(以及我还没讨论过的其他一堆特性)。我还将在Silverlight 2 Beta1版发布之后,把上面的例程提供下载,这么你可以自己打开和运行其代码了。
希望本文对你有所帮助,
Scott
This topic provides error message tables associated with Microsoft Silverlight error events.
It contains the following sections:
- OnError Event Error Table
- MediaFailed Event Error Table
- ImageFailed Event Error Table
- DownloadFailed Event Error Table
OnError Event Error Table
The following errors might be returned by the OnError event.
ErrorMessage | ErrorType | ErrorCode | Description |
---|---|---|---|
AG_E_UNKNOWN_ERROR | ANY | 1001 | The default error code that is bubbled up if no other specific error message is available. This error can apply to any call. |
AG_E_INIT_CALLBACK | initializeError | 2100 | Error in callback to the host script engine. This error occurs on initialization of the plug-in instance. |
AG_E_INIT_ROOTVISUAL | initializeError | 2101 | Error in visual root of the XAML tree. For example, you would get this error if the XAML root element is not a Canvas. Can also be raised if there are storyboard mismatches, such as referencing a Storyboard.TargetProperty that is not supported by the object that is the Storyboard.TargetName. This error occurs on initialization of the plug-in instance. |
AG_E_RUNTIME_INVALID_CALL | runtimeError | 2201 | Error returned when the particular call is not supported on that element. This error applies to all elements. |
AG_E_RUNTIME_FINDNAME | runtimeError | 2202 | The call to the FindName method failed. This applies to any element that FindName is supposed to find but cannot. |
AG_E_RUNTIME_SETVALUE | runtimeError | 2203 | Failure to set the value of a property. This applies both to standard JavaScript dotted property syntax, and to SetValue method calls. |
AG_E_RUNTIME_GETVALUE | runtimeError | 2204 | Failure to get the value of a property. This applies both to standard JavaScript dotted property syntax, and to GetValue method calls. |
AG_E_RUNTIME_ADDEVENT | runtimeError | 2205 | The AddEventListener method failed. |
AG_E_RUNTIME_DELEVENT | runtimeError | 2206 | The RemoveEventListener method failed. |
AG_E_RUNTIME_METHOD | runtimeError | 2207 | Error in a run-time method that does not have a specific error message. In a try/catch error object, the name of the method is appended to the string (for example, "AG_E_RUNTIME_METHOD : createFromXAML"). |
AG_E_RUNTIME_GETHOST | runtimeError | 2208 | Error in getting the host object. This applies to the GetHost method. |
AG_E_RUNTIME_GETPARENT | runtimeError | 2209 | Error in getting the parent of an object. This applies to the GetParent method. Note that only Canvas objects can be parents of other objects. |
AG_E_INVALID_ARGUMENT | runtimeError | 2210 | An invalid argument has been passed. |
AG_E_UNNAMED_RESOURCE | runtimeError | 2211 | Error raised when an unnamed Storyboard is added to the Resources section of a UIElement. |
AG_E_UNABLE_TO_PLAY | mediaError | 3000 | See the MediaFailed table. |
AG_E_INVALID_FILE_FORMAT | MediaError, imageError, downloadError | 3001 | See the MediaFailed table and the ImageFailed table. |
AG_E_NOT_FOUND | MediaError, imageError | 3002 | See the MediaFailed table and the ImageFailed table. |
AG_E_ABORT_FAILED | downloadError | 4000 | See the DownloadFailed table. This error applies to the Downloader object. |
AG_E_CONNECTION_ERROR | downloadError | 4001 | See the DownloadFailed table. This error applies to the Downloader object. |
AG_E_NETWORK_ERROR | downloadError | 4002 | See the DownloadFailed table. This error applies to the Downloader object. |
MediaFailed Event Error Table
The following errors might be returned by the MediaFailed event.
ErrorMessage | Description |
---|---|
AG_E_NETWORK_ERROR | Error raised when attempting to play back a non-existent or invalid media file from a third-party domain. |
AG_E_INVALID_FILE_FORMAT | This error can be raised for the following reasons:
|
AG_E_NOT_FOUND | The player will return this error from a call to GetMediaItem or GetMediaStreamItem (the native Windows Media APIs) if the media element asks for an item whose GUID is not recognized, or if the file does not exist at the URL specified. |
ImageFailed Event Error Table
The following errors might be returned by the ImageFailed Event.
ErrorMessage | Description |
---|---|
AG_E_INVALID_FILE_FORMAT | (Same-domain only) The file indicated by the URI is not supported on this type of element. For example, this error might occur if you pass a .wmv file URI to ImageSource. This error is reported only if the source is not cross-domain. |
AG_E_NOT_FOUND | (Same-domain only) The file indicated by the URI was not found at the position indicated by the URI. This error is reported only if the source is not cross-domain. |
AG_E_NETWORK_ERROR | Error reported for any cross-domain errors, to prevent anyone who is calling Silverlight APIs from discovering the existence (or nonexistence) of files on third-party servers. |
DownloadFailed Event Error Table
The following errors might be returned by the DownloadFailed Event.
ErrorMessage | Description |
---|---|
AG_E_ABORT_FAILED | Error raised when a call to Abort failed for some reason and the connection is still in progress. |
AG_E_CONNECTION_ERROR | Error raised from a call to Send. This error occurs before accessing the server when a failure to connect to the Internet occurs on the client side. |
AG_E_NETWORK_ERROR | Error resulting from a call to Send when the error has occurred on the server side. This error can also occur if you implicitly or explicitly attempt to use the Downloader to download a file: scheme URI. |

Ajax 无疑是最流行的新 Web 技术,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。它采用客户端脚本与 Web 服务器交换数据,所以,不必采用会中断交互的完整页面刷新,就可以动态地更新 Web 页面。使用 Ajax,可以创建更加丰富、更加动态的 Web 应用程序用户界面,其即时性与可用性甚至能够接近本机桌面应用程序。
Ajax 由 HTML、JavaScript、DHTML 和 DOM 组成。本系列的作者 Brett McLaughlin 是一位 Ajax 专家,他演示了这些技术如何协同工作 —— 从总体概述到细节的讨论 —— 使高效的 Web 开发成为现实。
系列文章
![]() |
第 1 部分: Ajax 简介 (2006 年 1 月 4 日)
Ajax 由 HTML、JavaScript、DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。本文的作者是一位 Ajax 专家,他演示了这些技术如何协同工作 —— 从总体概述到细节的讨论 —— 使高效的 Web 开发成为现实。他还揭开了 Ajax 核心概念的神秘面纱,包括 XMLHttpRequest 对象。
第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 (2006 年 2 月 16 日)
多数 Web 应用程序都使用请求/响应模型从服务器上获得完整的 HTML 页面。常常是点击一个按钮,等待服务器响应,再点击另一个按钮,然后再等待,这样一个反复的过程。有了 Ajax 和 XMLHttpRequest 对象,就可以使用不必让用户等待服务器响应的请求/响应模型了。本文中,Brett McLaughlin 介绍了如何创建能够适应不同浏览器的 XMLHttpRequest 实例,建立和发送请求,并响应服务器。
第 3 部分: Ajax 中的高级请求和响应 (2006 年 3 月 23 日)
对于很多 Web 开发人员来说,只需要生成简单的请求并接收简单的响应即可;但是对于希望掌握 Ajax 的开发人员来说,必须要全面理解 HTTP 状态代码、就绪状态和 XMLHttpRequest 对象。在本文中,Brett McLaughlin 将向您介绍各种状态代码,并展示浏览器如何对其进行处理,本文还给出了在 Ajax 中使用的比较少见的 HTTP 请求。
第 4 部分: 利用 DOM 进行 Web 响应 (2006 年 4 月 10 日)
程序员(使用后端应用程序)和 Web 程序员(编写 HTML、CSS 和 JavaScript 上)之间的分水岭是长久存在的。但是,Document Object Model (DOM) 弥补了这个裂缝,使得在后端使用 XML 同时在前端使用 HML 切实可行,并成为极其有效的工具。在本文中,Brett McLaughlin 介绍了 Document Object Model,解释它在 Web 页面中的应用,并开始挖掘其在 JavaScript 中的用途。
第 5 部分: 操纵 DOM (2006 年 4 月 27 日)
上一期中 Brett 介绍了文档对象模型(DOM),它的元素在幕后定义了 Web 页面。这一期文章中他将进一步探讨 DOM。了解如何创建、删除和修改 DOM 树的各个部分,了解如何实现网页的即时更新!
第 6 部分: 建立基于 DOM 的 Web 应用程序 (2006 年 10 月 12 日)
Brett McLaughlin 通过一个具体的 DOM 应用程序结束了他的 DOM 编程三部曲。
第 7 部分: 在请求和响应中使用 XML(1) (2006 年 10 月 23 日)
Brett McLaughlin 示范了如何使用 XML 数据格式发送异步请求。
第 8 部分:在请求和响应中使用 XML(2) (2006 年 10 月 23 日)
这篇文章主要探讨在大多数情况下 确实是 好主意的一种做法:向客户机返回 XML 响应。
第 9 部分:使用 Google Ajax Search API (2007 年 3 月 1 日)
发出异步请求并不意味着只是与您自己的服务器端程序交互。其实也可以与一些公共 API,例如来自 Google 或 Amazon 的 API 进行通信,从而为 Web 应用程序增加您自己的脚本和服务器端程序所不能提供的更多功能。本文将教您如何向公共 API,例如 Google 提供的 API 发出请求并接收其响应。
第 10 部分:使用 JSON 进行数据传输 (2007 年 4 月 9 日)
在异步应用程序中发送和接收信息时,可以选择以纯文本和 XML 作为数据格式。掌握 Ajax 的这一期讨论另一种有用的数据格式 JavaScript Object Notation(JSON),以及如何使用它更轻松地在应用程序中移动数据和对象。
第 11 部分:服务器端的 JSON (2007 年 8 月 28 日)
在最后一篇文章中,您将会学习如何处理以 JSON 格式发送到服务器的数据以及如何使用相同格式对脚本进行回复。
2007 年 10 月 29 日
在这个一切都要求新奇的世界中,要吸引用户的注意实属不易。了解如何在 Ajax 工具中使用 lightbox、弹出、窗口和渐变消息之类的新技术吸引用户的目光。
这可能是流传在都市中的一个传奇故事。很多年之前就有人和我说过这样一个用户交互体验。测试者的座位下面塞了 100 美金,而他正在使用计算机中的桌面应用程序。这个应用程序的状态栏中显示了这样一条信息:“在您的座位下面有 100 美金。”可悲的是,没有一个参与者能够发现他座位下面的钱。这个故事告诉我们状态栏传递信息的效率有多低,而且要吸引用户的注意绝非易事。
本文将介绍如何结合 PHP、动态 HTML(DHTML)和异步的 JavaScript + XML(Ajax)为内容增色,从而真正吸引用户的眼球。
![]() |
在浏览器中设置状态栏相当简单,但是要实现一些有用的功能(比如说弹出一个工具提示)则不是那么容易。考虑到简单性,我选择使用了一个可从网络上免费获得的工具提示库,它构建于出色的 Prototype.js JavaScript 库之上。清单 1 显示了这个工具提示的代码。
清单 1. index.html
<html> <head> <script src="prototype.js" type="text/javascript"></script> <script src="tooltip.js" type="text/javascript"></script> <style> body { font-family: arial,verdana; } .popup { padding:10px; border:1px solid #ccc; background:#eee; width:250px; font-size: small; } </style> </head> <body> <div id="book1">Code Generation In Action</div> <div id="popup1" class="popup"> </div> </body> <script type="text/javascript"> new Ajax.Updater( 'popup1', 'text.php' ); new Tooltip('book1', 'popup1') </script> </html> |
该页面首先使用一个 Ajax 调用更新工具提示的内容,方法是使用 Prototype.js 库中的 Ajax.Updater
类。然后再使用工具提示库所提供的 Tooltip
类将工具提示分配给 book1 <div>
标记。
清单 2 显示了该工具提示内容的代码。
清单 2. text.php
An excellent book on code generation and generative programming by Jack Herrington. |
现在,可以在浏览器中打开页面以查看效果。显示的页面如 图 1 所示。
图 1. 鼠标未移到文本上

当我把鼠标移到文本上,页面将弹出一个小窗口,如 图 2 所示。
图 2. 弹出窗口

![]() |
|
工具提示是一种整洁的页面呈现方式,并能根据用户的需要显示内容。如果某个用户想了解某项内容的更多信息,只需将鼠标移到该内容上便可显示详细信息。这些详细信息可具有不同的复杂度,可以是图像、表格和格式化数据。
![]() ![]() |
![]()
|
Lightbox 是一种最前沿的创新方法,可以将用户的注意力集中到页面上的某个特定元素。在下面的示例中,我在页面中添加了一个缩略图,当用户单击它时便会在 “lightbox” 中显示出大图。
要创建这种效果,我将使用极为优秀的 Lightbox JS 2.0 库,它同样构建于 Prototype.js 框架之上。清单 3 显示了示例代码。
清单 3. index.html
<html> <head> <link rel="stylesheet" href="css/lightbox.css" type="text/css" media="screen" /> <script src="js/prototype.js" type="text/javascript"></script> <script src="js/scriptaculous.js?load=effects" type="text/javascript"></script> <script src="js/lightbox.js" type="text/javascript"></script> </head> <body> <a href="images/megan1_400_320.jpg" rel="lightbox"> <img src="images/megan1_400_320.jpg" width="100" height="80" alt="Megan" border="0" /></a> </body> </html> |
在浏览器中打开该页面时,只能看到缩略图,如 图 3 所示。
图 3. 单击缩略图之前的显示效果

当我单击该缩略图时,实际大小的图像将优雅地显示在窗口中央,如 图 4 所示。
图 4. 显示实际大小图像的 lightbox

此外,背景中的所有其他内容将变成灰色,这样用户将更容易注意到页面中间显示的内容。
![]() |
|
如果您对 lightbox 这个术语还不太熟悉也没有关系:因为它是摄影行业中的一个相当深奥的词汇。在过去胶片摄影的时代,lightbox 是一个 6 英寸高,长宽皆为几英尺的盒子形状的设备,顶部涂有塑性白漆,盒子中间的小灯可以为整个表面提供照明。因此, 我们可以将幻灯片和底片放在 lightbox 上,然后使用一种小型放大镜来检查图像。您可以认为图 4 中的效果就是在通过 lightbox 上的放大镜查看照片。因此,lightbox 的术语便从此而来。
但是,是否可以将图像换成文本,并实现同样的效果呢?
Particle Tree 这个站点就使用这种与众不同的方法实现了 lightbox。此方法的优点便是可以显示使用 Ajax 从服务器获取的任意 HTML 代码。我将使用这种方法将额外的文本显示给用户。
清单 4 显示了主页代码。
清单 4. index.html
<html> <head> <title> Lightbox Text Test </title> <link rel="stylesheet" href="css/default.css" media="screen,projection" type="text/css" /> <link rel="stylesheet" href="css/lightbox.css" media="screen,projection" type="text/css" /> <script type="text/javascript" src="scripts/prototype.js"></script> <script type="text/javascript" src="scripts/lightbox.js"></script> </head> <body> <a href="text.php" class="lbOn">More About This Article</a> </body> </html> |
清单 5 中的 HTML 代码将通过 Ajax 获取并随后显示给用户。
清单 5. text.php
<p>This article covers the basics of AJAX Lightbox that shows text blocks instead of images</p> <p><a href="#" class="lbAction" rel="deactivate"> Return to article list</a></p> |
以上代码在浏览器中的显示效果如 图 5 所示。
图 5. 单击文本便可获得更多信息

当我单击文本时,可以看到页面内容将突出显示出来。请参见 图 6。
图 6. 运行中的文本 lightbox

![]() |
|
这种方法可以为页面上列出的产品或文章显示额外信息,而不必使用户离开当前页面。相反,您将间接地将用户的注意力转移到这些内容上。与 HTML 代码一样,这些信息可以包括更多的文本内容、图像,或者甚至是表单(比如说注册、评论或登录表单)。
![]() ![]() |
![]()
|
我在上一示例中提到过使用 lightbox 显示表单,但是这并不是用户在使用表单时真正需要的。他们真正需要的是窗口。所幸的是,Prototype 库提供了一个极好的窗口实现,该窗口实现具有各种不同的皮肤可满足您的需要。
窗口代码还将使用 Ajax 通过 Prototype 获取将在窗口框架中显示的内容。首先,开发托管窗口的基本页面,如 清单 6 所示。
清单 6. index.html
<html> <head> <script type="text/javascript" src="javascripts/prototype.js"></script> <script type="text/javascript" src="javascripts/effects.js"></script> <script type="text/javascript" src="javascripts/window.js"></script> <script type="text/javascript" src="javascripts/window_effects.js"></script> <link href="themes/default.css" rel="stylesheet" type="text/css" ></link> <link href="themes/spread.css" rel="stylesheet" type="text/css" ></link> </head> <body> <a href="javascript:void showWindow();">Show Window</a> <script> function showWindow() { win = new Window( { className: 'spread', url: 'test.html', title: 'Simple Window', width:400, height:300, destroyOnClose: true, recenterAuto:false } ); win.showCenter(); } </script> </body> </html> |
此处的 JavaScript 代码将响应单击 Show window 按钮的操作,结果是创建一个具有指定宽度、高度、标题和内容(内容由特定的 URL 指定)的窗口。然后使用 showCenter()
方法显示窗口,窗口将显示在在浏览器窗口的中部。
清单 7 显示了窗口的内容。
清单 7. test.html
<h1>Registration</h1> <p>You need to first register the product before...</p> |
该页面在浏览器的显示效果如 图 7 所示。
图 7. 窗口链接

页面中并没有什么内容,但是单击窗口链接之后却是另一番景色。如 图 8 所示。
图 8. 弹出窗口

有点华而不实的感觉,但是它确实可以吸引用户的注意力。除了石灰绿之外,您还可以选择一些不同的皮肤。
但是我真正想要的是弹出表单,不是吗?我特别想在主页上实现一个登录表单,当我单击 Login 按钮时便会弹出一个登录表单。清单 8 显示了主页的代码。
清单 8. form.php
<html> <head> <script type="text/javascript" src="javascripts/prototype.js"></script> <script type="text/javascript" src="javascripts/effects.js"></script> <script type="text/javascript" src="javascripts/window.js"></script> <script type="text/javascript" src="javascripts/window_effects.js"></script> <link href="themes/default.css" rel="stylesheet" type="text/css" ></link> <link href="themes/spread.css" rel="stylesheet" type="text/css" ></link> </head> <body> <div id="myloginform" style="display:none;overflow:clip;padding:10px;"> <form id="loginfrm"> <table> <tr><td>Login</td><td><input type="text" name="name" /></td></tr> <tr><td>Password</td><td><input type="password" name="password" /></td></tr> </table> </form> <button onclick="login()">Login</button> </div> <a href="javascript:void showWindow();">Login</a> <script> var g_loginWindow = null; function login() { new Ajax.Request( 'login.php', { parameters: $('loginfrm').serialize(), method: 'post', onSuccess: function( transport ) { g_loginWindow.close(); } } ); } function showWindow() { g_loginWindow = new Window( { className: 'spread', title: "Login", destroyOnClose: true, onClose:function() { $('myloginform').style.display = 'none'; } } ); g_loginWindow.setContent( 'myloginform', true, true ); g_loginWindow.showCenter(); } </script> </body> </html> |
这次,窗口的内容将直接存放在页面中。但是,当用户单击表单上的 Login 按钮时,页面将使用 Ajax.Request
对象向服务器请求登录表单。清单 9 显示了这个简单的登录脚本,实际中的实现将远没有这么简单。
清单 9. login.php
<true /> |
这时,当我在浏览器中打开该页面时将看到一个登录链接,如 图 9 所示。
图 9. login 链接

当我单击该链接时,将看到一个非常酷的 Web 2.0 样式的登录窗口,如 图 10 所示。
图 10. login 窗口

![]() |
|
当用户单击 Login 按钮时,页面将把用户名和密码发送给服务器。然后,服务器将验证凭证并建立一个会话 cookie,并回复响应,指示页面返回主页。
实际上,此类功能可以在应用程序中实现弹出窗口,并让用户感觉自己仿佛更像是在使用桌面应用程序,而不是在访问 Web 页面。
![]() ![]() |
![]()
|
与用户通信的另一种新方法是渐变消息 — 也就是,这种消息将在屏幕的一个重要位置弹出,告诉用户某些重要的事情。在本例中,我将使用 Scriptaculous 效果库(它也构建于 Prototype.js 之上)实现渐变消息。。
首先,我们从 清单 10 开始。
清单 10. index.html
<html><head> <style> .alert { opacity: 0.0; border:2px dashed black; padding:5px; background:#eee; font-family: arial, verdana; font-weight: bold; } </style> <script src="lib/prototype.js"></script> <script src="src/effects.js"></script> <script> function submit() { new Ajax.Updater( 'result', 'alert.html', { method: 'get', onSuccess: function() { new Effect.Opacity('result', { duration: 2.0, from: 0.0, to: 1.0 } ); new Effect.Opacity('result', { delay: 10.0, duration: 2.0, from: 1.0, to: 0.0 } ); } } ); } </script> </head><body> <div id="result" class="alert"></div><br/><br/> <button onclick="submit()">Submit</button> </body></html> |
在理想情况下,该页面有点类似含有 Submit 按钮的表单。然后,当用户单击 Submit 按钮时,服务器接收到提交的表单数据后将返回一个消息。这个消息将突出显示在某个位置,然后效果将渐渐减弱。在本例中,我省去了表单元素,因此页面中只有一个 Submit 按钮。
Submit 按钮将 Ajax 请求发送给 alert.html 页面。然后,将该页面的结果存放在 result <div>
标记中,Scriptaculous 效果类可以使该标记显示为渐变效果。
清单 11 显示了 alert 页面的代码。
清单 11. alert.html
A new record has been added. |
该页面中浏览器中的显示效果如 图 11 所示。
图 11. 表单的 Submit 按钮

还是一样,页面中并没有什么内容。可以考虑在 Submit 按钮上面加入一些含有数据的表单字段。
当我单击 Submit 按钮时,页面将突出显示警告提示,如 图 12 所示。
图 12. 渐变效果的消息

![]() |
|
几秒钟之后,消息将逐渐消失。
这种与用户交互的方式虽然简单,但是十分有效。只要别过度使用,它可以直接让用户感受到对象的出现和消失。这是人类与生俱来的本能。因此,您会自然地注意到。只要能够合理地使用这些技巧,吸引用户的注意力将不再困难。
![]() |
希望本文中的工具可以让您通过创新的方式实现交互和提示。随着时间的推移,我确信这些技巧将过度使用,并最终落得与状态栏一样的下场。但是在开始阶段,这些工具将提供一种有趣、有效且符合 Web 2.0 的吸引用户注意的方式。
![]() ![]() |
![]()
|
描述 | 名字 | 大小 | 下载方法 |
---|---|---|---|
示例代码 | x-ajaxxml6-lightbox.zip | 1573KB | HTTP |
![]() | ||||
![]() |
关于下载方法的信息 |