Web - 行者无疆 始于足下 - 行走,思考,在路上

Programming C#

1 课业要求

这半年有一门《C#程序设计》的课程,借着这个契机,匆匆学了下C#,并做了一个极其简陋的“大程”。

程序的要求基本如下:

  • 用C#实现一个数据库操作网页代码生成工具。需要实现的基本功能如下:
    1. 列出数据库中所有表供用户选择
    2. 用户选择一个表后生成若干网页,能对选定的表提供list、add、modify、delete等操作,不能使用GridView控件,需要用标准的HTML元素实现
    3. 能够分析表中每个字段的类型,在add、modify界面上根据字段的类型使用合适的Web组件,需要能正确处理数字、字符、日期等类型
    4. List的时候能够自动处理分页
    5. 为了提交作业方便,数据库使用access,提供对话框让用户选择数据库

我大概花了一周左右的时间完成了程序,这其中包括:三天的时间熟悉C#和Mono,一天的时间复习SQL语法并学习Sqlite的使用,一天的时间学习下ASP.NET,一天时间完成程序,最后一天的时间用来看新版《水浒传》……^_

最终的效果自然是十分“简陋”,只实现了第1、4、5条的需求和第2、3条的部分需求,而且还存在严重的bug。不过时间紧迫,加上我对微软的快餐文化无爱,就匆匆忙忙交了作业,忙下一门考试去了。

简单说下实现思路吧,顺便总结下学习C#过程中的一些心得。

实验的基本条件:

  • OS: Arch Linux
  • IDE: MonoDevelop 2.4.2
  • Language: C# implemented by mono project
  • Web Server: xsp implemented by mono project
  • Database: Sqlite 3.7.4

2 Mono

引用mono-project主页上的说法,mono is "An open source, cross-platform, implementation of C# and the CLR that is binary compatible with Microsoft.NET", MonoDevelop is "An open Source C# and .NET development environment for Linux, Windows, and Mac OS X"。虽然在Linux下用Mono来搞C#是件不怎么“光彩”的事情,但是mono却给我留下了极佳的用户体验。代码补全、重构,多语言支持,内建xsp server,集成调试功能,还有让我欢呼流泪的Editor的Vi-mode的支持。

那么Mono到底是个什么东西呢?直白点的说法就是,Mono是Microsoft .NET的跨平台实现。比如我们可以用C#写如下一个程序winform.cs:

using System;
using System.Windows.Forms;

public class HelloWorld : Form
{
    static public void Main()
    {
        Application.Run(new HelloWorld());
    }

    public HelloWorld()
    {
        Text = "Hello, Mono World";
    }
}

程序的功能十分简单:创建一个窗口并将窗口标题设为"Hello, Mono World"。

我们用如下的命令编译运行此程序:

gmcs -pkg:dotnet winform.cs && mono winform.exe

然后屏幕上就会显示一个窗口。将winform.exe拷贝到一个装有.NET的windows中,程序也是可以运行的。

3 Sqlite

基于程序跨平台的考虑,C#的运行环境我选择了Mono,而数据库则抛弃了MicroSoft Access,选择了Sqlite,也借此契机学习下这个世界上最流行的嵌入式数据库引擎。

什么是嵌入式数据库?传统的数据库,如MySQL,采用的是Client/Server架构。而Sqlite采用的Serverless架构。Sqlite所有的读写都直接应用于一个跨平台的磁盘文件。Sqlite的特性有:

  • ACID事务
  • 零配置 – 无需安装和管理配置
  • 储存在单一磁盘文件中的一个完整的数据库
  • 数据库文件可以在不同字节顺序的机器间自由的共享
  • 支持数据库大小至2TB
  • 足够小, 大致3万行C代码, 250K
  • 比一些流行的数据库在大部分普通数据库操作要快
  • 良好注释的源代码, 并且有着90%以上的测试覆盖率
  • 独立: 没有额外依赖
  • Source完全的Open, 你可以用于任何用途, 包括出售它
  • 支持多种开发语言,C, PHP, Perl, Java, ASP .NET,Python

Sqlite作为一个示范性的学习型开源项目也是一个非常理想的选择。在Sqlite的主页上有sqlite-amalgamation-3070400.zip下载,这是一个组合了所有Sqlite的C代码在一个单独文件中的压缩挡。是学习数据库设计与实现的极好资源。

Sqlite在很多著名的开源软件项目中都有重要的应用。引用《The Definisive Guide to Sqlite》中的一段话:

"If you are a programmer, imagine how much code it would take to implement the following SQL statement in your program:

SELECT AVG(z-y) FROM table GROUP BY x HAVING x > MIN(z) OR x < MAX(y) ORDER BY y DESC LIMIT 10 OFFSET 3;

If you are already familiar with SQL, imagine coding the equivalent of a subquery, compound query, GROUP BY clause or multiway join—in C. SQLite embeds all of this functionality into your application with minimal cost. With a database engine integrated directly into your code, you can begin to think of SQL as a domain-specific language in which to implement complex sorting algorithms in your program. "

记得大二下学期伊始学习Java,要编写一个浙江大学校车查询系统的软件,那个时候还没有学过数据库,就想破脑门地琢磨该怎么样采用Java实现复杂的校车查询算法,甚至想要去研究各种图论算法云云。直到两个月后学习了数据库原理,情况才逐渐明朗。最终的程序采用的是Apache Derby,另一款Java实现的嵌入式数据库。关于Sqlite和Derby的对比,可以参考Sqlite Versus Derby

我们可以用如下的命令找出系统中的Sqlite数据库文件:

sudo updatedb && for file in `locate *.db`
do
file $file
done | grep -i "sqlite" | awk '{print $1}'

Sqlite比较好用的GUI工具有sqlitebrowsersqliteman

Sqlite具有多种语言的bindings,关于C#的binding还有些小小的麻烦,因为Sqlite的binding并不是ECMA C#标准的一部分,所以MS C#和Mono C#对此的实现有些许差别。Mono通过Mono.Data.Sqlite实现访问Sqlite的ADO.NET,具体的示例代码如下所示:

  • 通过IDataReader:
using System;
using System.Data;
using Mono.Data.Sqlite;

public class Test
{
	public static void Main (string[] args)
	{
		string connectionString = "URI=file:/home/lox/test.db";
		IDbConnection dbcon;
		dbcon = (IDbConnection)new SqliteConnection (connectionString);
		dbcon.Open ();
		IDbCommand dbcmd = dbcon.CreateCommand ();
		// requires a table to be created named employee
		// with columns firstname and lastname
		// such as,
		//        CREATE TABLE employee (
		//           firstname varchar(32),
		//           lastname varchar(32));
		string sql = "SELECT * " + "FROM test";
		dbcmd.CommandText = sql;
		IDataReader reader = dbcmd.ExecuteReader ();
		while (reader.Read ()) {
			int FirstName = reader.GetInt32(0);
			string LastName = reader.GetString (1);
			Console.WriteLine ("Name: " + FirstName.ToString() + " " + LastName);
		}
		// clean up
		reader.Close ();
		reader = null;
		dbcmd.Dispose ();
		dbcmd = null;
		dbcon.Close ();
		dbcon = null;
	}
}
  • 通过DataSet:
using System;
using System.Data;
using System.Data.SqlClient;
using Mono.Data.Sqlite;

public class Test
{
	public static void Main (string[] args)
	{
		string connectionString = "URI=file:/home/lox/user.db";
		string commandString = "select * from py_phrase_0";
		
		SqliteDataAdapter dataAdapter = 
			new SqliteDataAdapter(commandString, connectionString);
		
		DataTable dataTable = new DataTable();
		dataAdapter.Fill(dataTable);
		
		foreach (DataRow dataRow in dataTable.Rows)
		{
			Console.WriteLine(dataRow["phrase"].ToString());
		}
	}
}

话说ADO.NET的DataSet和ASP.NET中某些控件的bind功能还真是挺方便的。

4 ASP.NET

ASP.NET?这究竟是个什么东西?大一时学了一门课叫做《WEB数据库设计》,讲的是ASP,诸如如何配置IIS,如何在Dreamweaver中添加Access数据源、连接数据库,以及VBScript的入门语法等等。三年之后我才知道,IIS并不是Apache的对手,Apache在某些方面也不如nginx,LAMP架构才是web服务中基础中的基础;编写html最好用的不是Dreamweaver而是vim;Access充其量只是个不跨平台比Excel强点有限的玩具数据库产品;ASP日薄西山,已经i躺在了历史的博物馆里了;当初对ASP的吹嘘——动态网页技术,如今又成了ASP的最大诟病——代码混杂,无法分离网页设计和业务逻辑——而这又成了ASP.NET横空出世的理由。至于ASP.NET能活多久,我不关心也不在乎,我所在乎的只是用这个东西尽快地完成我的大程序。

理解ASP.NET的核心在于亮点,一是MVC架构的理解,即业务逻辑和页面表现的分离;二是Windows事件机制和消息循环机制。

MVC(Model, View, Control)是当今网站中比较流行的架构。其最大的贡献在于实现了网站业务逻辑与页面表现美工的分离。最初的动态网页,无论是ASP、JSP还是PHP也好,静态的html代码和程序语言代码混杂在一起,造成了大规模web程序非常难于书写和维护。后来Java出现了各种各样的框架如当下流行的SSH(Struts、Spring、Hibernate);微软革了ASP的命推出了ASP.NET,以C#和VB.NET为后端实现MVC架构;PHP也有各种各样现成的数不清的框架。框架这个东西是最容易过时的。所以我觉得框架这个东西就像山东大饼,饱腹可以,太过深究细节就有些得不偿失,重要的还是要掌握柴米油盐。用框架人人都会,但是设计并实现出一个优秀的框架,就不是嘴上说说那么容易了。微软的快餐产品让千百万人踏入了程序设计的大门,也让他们陷入了跟潮流的漩涡。而一切微软技术的核心,定有躲不开的核心,那就是Win32 API和消息循环机制。

深入探讨这个问题已经远远超出了本人的能力。本人也只是窥探了几章《Windows程序设计》,才到这里才大放厥词。什么是消息循环?事实上消息循环绝不向消息循环那么简单,消息循环和OO、结构化程序设计一样,是一种Architectural Patterns。常见的Architectural Patterns(参考Software Architecture in Practice (2nd Edition)有:

  • Layered
  • Generalization(OO)
  • Pipe-and-filter
  • Shared-data
  • Publish-subscribe(event-based)
  • Client-server
  • Peer-to-peer
  • Communicating process
  • ……

消息循环属于Publish-subscribe,它是Windows事件机制的基础。而消息循环中很重要的两点一个是消息队列,另外就是Callback Functions(回调函数)。形像的讲,我们设每个事件为x,而处理事件x的函数为X。假设我们的一个系统软件依次出发a、b、c、d四个事件,那么消息队列中有abcd四个事件,然后由操作系统根据消息队列来决定下一步该做哪些事情。比如Windows看到了消息队列中的第一个事件为a,那么Windows就会调用A来处理事件a,a处理完毕后出队,接下来的事件是b,那么就调用B来处理时间b。没错,ABCD等Callback Function是有操作系统来调用,而不需要程序员在程序中显示调用,这也是它们被叫做Callback Function的原因。

理解消息循环对Windows程序设计是至关重要的,诸如MFC、C# Windows Forms和ASP.NET的所有事件处理机制都是基于消息循环。在一开始写GUI程序的时候常常程序的时候常常无法理解程序的执行流行,一来是结构化编程的思想根深蒂固,二来是没有完全理解Event-based程序的处理模式。那么另一个问题是,回调函数的机制又是怎样的呢?这个问题答案的关键字是函数指针,一个我们在C语言中学过、有点印象却很少用到的东西。函数指针也是C++多态性RTTI的关键所在!(参考《Thinking in C++, Volume 1》)。Java Swing的listener,QT的signal and slots机制,归根到底应该也是消息循环。Publish-subscribe, core of GUI programming。

差不多了。关于ASP.NET的絮叨到此为止吧,再下去就黔驴技穷了。如果再加一句,就是ASP.NET的控件还是挺好用的^_^

5 C#

最后谈到C#。简单的说,C++和Java入门之后,完全没有必要再学C#。C#能做的东西,Java都能做到,而且能做的更好。也算学了若干门Programming Languages,对语言之争已经看的很淡,更谈不上对某一门语言的死忠。在我看来,学习一门编程语言只能有两个结果:

  1. 给你的编程思想打开了新的一道门;
  2. 让你明白或巩固一个道理:trade-off是很重要的!

很不幸,对我来说,C#属于第二种,而Python和Shell Script属于第一种。C语言是指针的艺术,C++则有试图设计一种智能指针,Java抛弃了指针,只有C#,哆哆嗦嗦地使用着指针:unsafe code和delegate;C#的继承控制更为复杂,除了传统的public、protected、private,还有internal和protected internal;Java用import,包和文件目录有统一的物理逻辑关系,C#用using,包和文件目录很混乱,这到底是个优点还是个缺点?C++的class和struct几乎相同,C#却限制了struct的使用;C#还有一种类成员get/set的语法,我觉得这种语法糖特别恶心。更多的语言特性比较可以参考http://tech.it168.com/a2010/0817/1091/000001091254.shtml

写到这里我又想到,为什么会有如此多的Programmig Languages呢。假设把这些编程语言按照字母顺序排一下,让一个人去学,恐怕一辈子也学不完。github上有一个有趣的hello world项目,汇集了众多语言写的hello world程序,你可以通过如下命令获取这些程序:

git pull git://github.com/git/hello-world.git

面对如此多的编程语言,我们又该如何选择呢?著名黑客Eric Raymond给了我们有说服力的答案

"It's best, actually, to learn all five of Python, C/C++, Java, Perl, and LISP. Besides being the most important hacking languages, they represent very different approaches to programming, and each will educate you in valuable ways."

没错。虽然说解决问题是最终目的,方法手段有千千万,语言不是关键,思想是最重要的,但是选择语言往往也决定着你的思想,就比如你不太可能去用Python lambda, map, reduce去实现Functional Programming,也不太可能用lisp去写OO程序等等。

6 Learning Resources

.NET语言并没有C++语言如《The C++ Programming Language》和《C++ Template》这种重量级的传世著作,O'Reilly的《Programmig C#》《Programming ASP.NET》是非常不错的入门教材了。其余一切国内的中文xx教程、xx精通一虑不要看。

理解消息循环和Windows事件机制,最经典的莫过于Charles Petzold的《Programming Windows》,我虽然只看过前几章,但已经受益匪浅。

最终版的程序就不给了。区区几百行,bug一大堆,丢人的。如果实在有需要参考,可以给我发邮件。xiaohanyu1988@gmail.com。谢谢捧场。

豆瓣

 

验证失败  · · · · · ·

很抱歉,豆瓣没有在"行者无疆 始于足下"的RSS输出中发现正确的验证码。这有可能是你没有正确粘贴验证码,也可能是暂时性的网络故障。你可以在确认包含正确的验证码的文章已经发表后,再次点击页面下方的按钮提交验证。

如何声明拥有blog  · · · · · ·

很简单,你只要在"行者无疆 始于足下"上发一篇文章(验证成功后这篇文章可以删掉),在标题或者内容中包含下面这段文字:

doubanclaim99266982451c5af7

确认该段文字在RSS输出中存在,然后点击下面这个按钮就可以了。

w3cschool javascript 笔记(1)

Javascript 教程

1 简介

 

1.1 什么是Javascript

  • JavaScript被设计用来向HTML页面添加交互行为。
  • JavaScript是一种脚本语言(脚本语言是一种轻量级的编程语言)。
  • JavaScript由数行可执行计算机代码组成。
  • JavaScript通常被直接嵌入 HTML 页面。
  • JavaScript是一种解释性语言(就是说,代码执行不进行预编译)。
  • 所有的人无需购买许可证均可使用JavaScript。

1.2 真实的名称是ECMAScript

  • JavaScript的正式名称是"ECMAScript"。这个标准由ECMA组织发展和维护。
  • ECMA-262是正式的JavaScript标准。这个标准基于JavaScript(Netscape)和JScript(Microsoft)。
  • Netscape(Navigator 2.0)的Brendan Eich发明了这门语言,从1996年开始,已经出现在所有的Netscape和Microsoft浏览器中。
  • ECMA-262的开发始于1996年,在1997年7月,ECMA会员大会采纳了它的首个版本。
  • 在1998年,该标准成为了国际ISO标准(ISO/IEC 16262)。
  • 这个标准仍然处于发展之中。

2 如何实现JavaScript

  • <script>标签嵌入JavaScript
  • 与老的浏览器打交道:
    <html>
    <body>
    <script type="text/javascript">
    <!--
    document.write("Hello World!");
    //-->
    </script>
    </body>
    </html>
    

3 把JavaScript放置到何处

  • 位于 head 部分的脚本:当脚本被调用时,或者当事件被触发时,脚本就会被执行。当你把脚本放置到 head 部分后,就可以确保在需要使用脚本之前,它已经被载入了。
    <html>
    <head>
    <script type="text/javascript">
    ....
    </script>
    </head>
    ....
    
  • 位于 body 部分的脚本:在页面载入时脚本就会被执行。当你把脚本放置于 body 部分后,它就会生成页面的内容。
    <html>
    <head>
    </head>
    
    <body>
    <script type="text/javascript">
    ....
    </script>
    </body>
    </html>
    
  • 使用外部JavaScript
    • <script src="javascript.js">….<script>
    • 您可以把 .js 文件放到网站目录中通常存放脚本的子目录中,这样更容易管理和维护。

4 JavaScript语句

 

4.1 JavaScript语句

  • 浏览器把行末作为语句的结尾
  • 分号是可选的,通过使用分号,可以在一行中写多条语句。

5 JavaScript注释

  • 单行注释://comments
  • 多行注释:/*comments*/

6 JavaScript变量

  • 变量对大小写敏感(y和Y是两个不同的变量)
  • 变量必须以字母或下划线开始
  • 可以通过var语句来声明JavaScript变量
  • 可以在声明它们时向变量赋值
  • 如果您所赋值的变量还未进行过声明,该变量会自动声明
    • 这些语句:
      x=5;
      carname="Volvo"; 
      
    • 与这些语句的效果相同:
      var x=5;
      var carname="Volvo"; 
      
  • 如果您再次声明了JavaScript变量,该变量也不会丢失其原始值。

7 JavaScript运算符

  • 如果把数字与字符串相加,结果将成为字符串。

8 JavaScript比较和逻辑运算符

  • ==:等于
  • ===:全等

9 JavaScript If…Else语句

  • if
  • if … else
  • if … else if … else
  • switch

10 JavaScript消息框

 

10.1 警告框

  • 警告框经常用于确保用户可以得到某些信息。
  • 当警告框出现后,用户需要点击确定按钮才能继续进行操作。
  • alert("文本")

10.2 确认框

  • 确认框用于使用户可以验证或者接受某些信息。
  • 当确认框出现后,用户需要点击确定或者取消按钮才能继续进行操作。
  • 如果用户点击确认,那么返回值为true。如果用户点击取消,那么返回值为false。
  • confirm("文本")

10.3 提示框

  • 提示框经常用于提示用户在进入页面前输入某个值。
  • 当提示框出现后,用户需要输入某个值,然后点击确认或取消按钮才能继续操纵。
  • 如果用户点击确认,那么返回值为输入的值。如果用户点击取消,那么返回值为null。
  • prompt("文本", "默认值")

11 JavaScript函数

 

11.1 JavaScript函数

  • 将脚本编写为函数,就可以避免页面载入时执行该脚本。
  • 函数包含着一些代码,这些代码只能被事件激活,或者在函数被调用时才会执行。
  • 函数在页面起始位置定义,即 <head> 部分。

11.2 如何定义函数

 

11.2.1 创建函数的语法:

function func(var1, var2, ...)
{
    \\statements
}

11.2.2 JavaScript变量的生存期

  • 全局变量
  • 局部变量

12 JavaScript For循环

<html>
<body>

<script type="text/javascript">
var i=0
for (i=0;i<=10;i++)
{
    document.write("The number is " + i)
    document.write("<br />")
}
</script>

</body>
</html>

13 JavaScript While循环

<html>
<body>
<script type="text/javascript">
var i=0
while (i<=10)
{
    document.write("The number is " + i)
    document.write("<br />")
    i=i+1
}
</script>
</body>
</html>

14 JavaScript Break和Continue语句

  • break语句:使用break语句来终止循环。
  • continue语句:使用continue语句来终止当前的循环,然后从下一个值继续执行。

JavaScript For…In声明

<html>
<body>

<script type="text/javascript">
var x
var mycars = new Array()
mycars[0] = "Saab"
mycars[1] = "Volvo"
mycars[2] = "BMW"

for (x in mycars)
{
    document.write(mycars[x] + "<br />")
}
</script>

</body>
</html>

15 JavaScript事件

  • 事件是可以被JavaScript侦测到的行为。
  • 事件举例:
    • 鼠标点击
    • 页面或图像载入
    • 鼠标悬浮于页面的某个热点之上
    • 在表单中选取输入框
    • 确认表单
    • 键盘按键
  • JavaScript事件参考
    属性 当以下情况发生时,出现此事件 FF N IE
    onabort 图像加载被中断 1 3 4
    onblur 元素失去焦点 1 2 3
    onchange 用户改变域的内容 1 2 3
    onclick 鼠标点击某个对象 1 2 3
    ondblclick 鼠标双击某个对象 1 4 4
    onerror 当加载文档或图像时发生某个错误 1 3 4
    onfocus 元素获得焦点 1 2 3
    onkeydown 某个键盘的键被按下 1 4 3
    onkeypress 某个键盘的键被按下或按住 1 4 3
    onkeyup 某个键盘的键被松开 1 4 3
    onload 某个页面或图像被完成加载 1 2 3
    onmousedown 某个鼠标按键被按下 1 4 4
    onmousemove 鼠标被移动 1 6 3
    onmouseout 鼠标从某元素移开 1 4 4
    onmouseover 鼠标被移到某元素之上 1 2 3
    onmouseup 某个鼠标按键被松开 1 4 4
    onreset 重置按钮被点击 1 3 4
    onresize 窗口或框架被调整尺寸 1 4 4
    onselect 文本被选定 1 2 3
    onsubmit 提交按钮被点击 1 2 3
    onunload 用户退出页面 1 2 3

16 JavaScript Try…Catch语句

 

17 JavaScript特殊字符

代码 输出
\' 单引号
\" 双引号
\& 和号
\\ 反斜杠
\n 换行符
\r 回车符
\t 制表符
\b 退格符
\f 换页符

18 JavaScript指导方针

  • JavaScript对大小写敏感
  • JavaScript会忽略多余的空格
  • 您可以在文本字符串内部使用反斜杠对代码进行折行

19 JavaScript对象简介

  • JavaScript是面向对象的编程语言(OOP)。
  • 对象拥有属性和方法。
    • 属性:属性指与对象有关的值。
    • 方法:方法指对象可以执行的行为(或者可以完成的功能)。

20 JavaScript字符串(String)对象

  • 计算字符串的长度
    <html>
    <body>
    
    <script type="text/javascript">
    
    var txt="Hello World!"
    document.write(txt.length)
    
    </script>
    
    </body>
    </html>
    
  • indexOf()方法
    <html>
    <body>
    
    <script type="text/javascript">
    
    var str="Hello world!"
    document.write(str.indexOf("Hello") + "<br />")
    document.write(str.indexOf("World") + "<br />")
    document.write(str.indexOf("world"))
    
    </script>
    
    </body>
    </html>
    
  • match()方法
    <html>
    <body>
    
    <script type="text/javascript">
    
    var str="Hello world!"
    document.write(str.match("world") + "<br />")
    document.write(str.match("World") + "<br />")
    document.write(str.match("worlld") + "<br />")
    document.write(str.match("world!"))
    
    </script>
    
    </body>
    </html>
    
  • replace()方法
    <html>
    <body>
    
    <script type="text/javascript">
    
    var str="Visit Microsoft!"
    document.write(str.replace(/Microsoft/,"W3School"))
    
    </script>
    </body>
    </html>
    

20.1 String对象的方法

  • JavaScript的字符串是不可变的
  • String类定义的方法都不能改变字符串的内容
    方法 描述 FF N IE
    anchor() 创建 HTML 锚。 1 2 3
    big() 用大号字体显示字符串。 1 2 3
    blink() 显示闪动字符串。 1 2  
    bold() 使用粗体显示字符串。 1 2 3
    charAt() 返回在指定位置的字符。 1 2 3
    charCodeAt() 返回在指定的位置的字符的 Unicode 编码。 1 4 4
    concat() 连接字符串。 1 4 4
    fixed() 以打字机文本显示字符串。 1 2 3
    fontcolor() 使用指定的颜色来显示字符串。 1 2 3
    fontsize() 使用指定的尺寸来显示字符串。 1 2 3
    fromCharCode() 从字符编码创建一个字符串。 1 4 4
    indexOf() 检索字符串。 1 2 3
    italics() 使用斜体显示字符串。 1 2 3
    lastIndexOf() 从后向前搜索字符串。 1 2 3
    link() 将字符串显示为链接。 1 2 3
    localeCompare() 用本地特定的顺序来比较两个字符串。 1 4 4
    match() 找到一个或多个正在表达式的匹配。 1 4 4
    replace() 替换与正则表达式匹配的子串。 1 4 4
    search() 检索与正则表达式相匹配的值。 1 4 4
    slice() 提取字符串的片断,并在新的字符串中返回被提取的部分。 1 4 4
    small() 使用小字号来显示字符串。 1 2 3
    split() 把字符串分割为字符串数组。 1 4 4
    strike() 使用删除线来显示字符串。 1 2 3
    sub() 把字符串显示为下标。 1 2 3
    substr() 从起始索引号提取字符串中指定数目的字符。 1 4 4
    substring() 提取字符串中两个指定的索引号之间的字符。 1 2 3
    sup() 把字符串显示为上标。 1 2 3
    toLocaleLowerCase() 把字符串转换为小写。 - - -
    toLocaleUpperCase() 把字符串转换为大写。 - - -
    toLowerCase() 把字符串转换为小写。 1 2 3
    toUpperCase() 把字符串转换为大写。 1 2 3
    toSource() 代表对象的源代码。 1 4 -
    toString() 返回字符串。 - - -
    valueOf() 返回某个字符串对象的原始值 1 2 4

20.2 String对象的属性

属性 描述 FF N IE
constructor 对创建该对象的函数的引用 1 4 4
length 字符串的长度 1 2 3
prototype 允许您向对象添加属性和方法 1 2 4

21 JavaScript Date(日期)对象

  • 返回当日的日期和时间
    <html>
    <body>
    
    <script type="text/javascript">
    
    document.write(Date())
    
    </script>
    
    </body>
    </html>
    
  • getTime()
    <html>
    <body>
    
    <script type="text/javascript">
    
    var minutes = 1000*60
    var hours = minutes*60
    var days = hours*24
    var years = days*365
    var d = new Date()
    var t = d.getTime()
    var y = t/years
    
    document.write("It's been: " + y + " years since 1970/01/01!")
    
    </script>
    
    </body>
    
  • setFullYear()
    <html>
    <body>
    
    <script type="text/javascript">
    
    var d = new Date()
    d.setFullYear(1992,10,3)
    document.write(d)
    
    </script>
    
    </body>
    </html>
    
  • toUTCString()
    <html>
    <body>
    
    <script type="text/javascript">
    
    var d = new Date()
    document.write (d.toUTCString())
    
    </script>
    
    </body>
    </html>
    
  • 时钟
    <html>
    <head>
    <script type="text/javascript">
    function startTime()
    {
        var today=new Date()
        var h=today.getHours()
        var m=today.getMinutes()
        var s=today.getSeconds()
    
        // add a zero in front of numbers<10
        m=checkTime(m)
        s=checkTime(s)
        document.getElementById('txt').innerHTML=h+":"+m+":"+s
        t=setTimeout('startTime()',500)
    }
    
    function checkTime(i)
    {
        if (i<10) 
        {
            i="0" + i
        }
        return i
    }
    </script>
    </head>
    
    <body onload="startTime()">
    <div id="txt"></div>
    </body>
    </html>
    

21.1 Date对象的方法

方法 描述 FF N IE
Date() 返回当日的日期和时间 1 2 3
getDate() 从Date对象返回一个月中的某一天 (1 ~ 31) 1 2 3
getDay() 从Date对象返回一周中的某一天 (0 ~ 6) 1 2 3
getMonth() 从Date对象返回月份 (0 ~ 11) 1 2 3
getFullYear() 从Date对象以四位数字返回年份 1 4 4
getYear() 从Date对象以两位或四位数字返回年份。 1 2 3
getHours() 返回Date对象的小时 (0 ~ 23) 1 2 3
getMinutes() 返回Date对象的分钟 (0 ~ 59) 1 2 3
getSeconds() 返回Date对象的秒数 (0 ~ 59)) 1 2 3
getMilliseconds() 返回Date对象的毫秒(0 ~ 999) 1 4 4
getTime() 返回 1970 年 1 月 1 日至今的毫秒数 1 2 3
getTimezoneOffset() 返回本地时间与格林威治标准时间的分钟差 (GMT) 1 2 3
getUTCDate() 根据世界时从Date对象返回月中的一天 (1 ~ 31) 1 4 4
getUTCDay() 根据世界时从Date对象返回周中的一天 (0 ~ 6) 1 4 4
getUTCMonth() 根据世界时从Date对象返回月份 (0 ~ 11) 1 4 4
getUTCFullYear() 根据世界时从Date对象返回四位数的年份 1 4 4
getUTCHours() 根据世界时返回Date对象的小时 (0 ~ 23) 1 4 4
getUTCMinutes() 根据世界时返回Date对象的分钟 (0 ~ 59) 1 4 4
getUTCSeconds() 根据世界时返回Date对象的秒钟 (0 ~ 59) 1 4 4
getUTCMilliseconds() 根据世界时返回Date对象的毫秒(0 ~ 999) 1 4 4
parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数 1 2 3
setDate() 设置Date对象中月的某一天 (1 ~ 31)) 1 2 3
setMonth() 设置Date对象中月份 (0 ~ 11)) 1 2 3
setFullYear() 设置Date对象中的年份(四位数字) 1 4 4
setYear() 设置Date对象中的年份(两位或四位数字)。 1 2 3
setHours() 设置Date对象中的小时 (0 ~ 23) 1 2 3
setMinutes() 设置Date对象中的分钟 (0 ~ 59) 1 2 3
setSeconds() 设置Date对象中的秒钟 (0 ~ 59) 1 2 3
setMilliseconds() 设置Date对象中的毫秒 (0 ~ 999) 1 4 4
setTime() 通过向或从1970年1月1日午夜添加或减去指定数目的毫秒来计算日期和时间 1 2 3
setUTCDate() 根据世界时设置Date对象中月份的一天 (1 ~ 31) 1 4 4
setUTCMonth() 根据世界时设置Date对象中的月份 (0 ~ 11) 1 4 4
setUTCFullYear() 根据世界时设置Date对象中年份(四位数字) 1 4 4
setUTCHours() 根据世界时设置Date对象中小时 (0 ~ 23) 1 4 4
setUTCMinutes() 根据世界时设置Date对象中分钟 (0 ~ 59) 1 4 4
setUTCSeconds() 根据世界时设置Date对象中秒钟 (0 ~ 59) 1 4 4
setUTCMilliseconds() 根据世界时设置Date对象中毫秒S(0 ~ 999) 1 4 4
toSource() 代表对象的源代码 1 4 -
toString() 把Date对象转换为字符串。 1 2 4
toTimeString() 把Date对象的时间部分转换为字符串。 1 2 4
toDateString() 把Date对象的日期部分转换为字符串。 1 2 4
toGMTString() 根据格林威治时间,把Date对象转换为字符串。 1 2 3
toUTCString() 根据世界时,把Date对象转换为字符串。 1 4 4
toLocaleString() 根据本地时间格式,把Date对象转换为字符串。 1 2 3
toLocaleTimeString() 根据本地时间格式,把Date对象的时间部分转换为字符串 1 2 3
toLocaleDateString() 根据本地时间格式,把Date对象的日期部分转换为字符串 1 2 3
UTC() 根据世界时,获得一个日期,然后返回1970年1月1日午夜到该日期的毫秒数。 1 2 3
valueOf() 返回Date对象的原始值。 1 2 4

22 JavaScript数组

  • 创建数组
    <html>
    <body>
    
    <script type="text/javascript">
    var mycars = new Array()
    mycars[0] = "Saab"
    mycars[1] = "Volvo"
    mycars[2] = "BMW"
    
    for (i=0;i<mycars.length;i++)
    {
        document.write(mycars[i] + "<br />")
    }
    </script>
    
    </body>
    </html>
    
  • For…In声明
    <html>
    <body>
    <script type="text/javascript">
    var x
    var mycars = new Array()
    mycars[0] = "Saab"
    mycars[1] = "Volvo"
    mycars[2] = "BMW"
    
    for (x in mycars)
    {
    document.write(mycars[x] + "<br />")
    }
    </script>
    </body>
    </html>
    

22.1 Array对象的方法

方法 描述 FF N IE
concat() 连接两个或更多的数组,并返回结果。 1 4 4
join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。 1 3 4
pop() 删除并返回数组的最后一个元素 1 4 5.5
push() 向数组的末尾添加一个或更多元素,并返回新的长度。 1 4 5.5
reverse() 颠倒数组中元素的顺序。 1 3 4
shift() 删除并返回数组的第一个元素 1 4 5.5
slice() 从某个已有的数组返回选定的元素 1 4 4
sort() 对数组的元素进行排序 1 3 4
splice() 删除元素,并向数组添加新元素。 1 4 5.5
toSource() 代表对象的源代码 1 4 -
toString() 把数组转换为字符串,并返回结果。 1 3 4
toLocaleString() 把数组转换为本地数组,并返回结果。 1 3 4
unshift() 向数组的开头添加一个或更多元素,并返回新的长度。 1 4 6
valueOf() 返回数组对象的原始值 1 2 4

23 JavaScript Boolean(逻辑)对象

  • Boolean 对象是 JavaScript 的一种基本数据类型。
  • Boolean 对象是一个把布尔值打包的布尔对象。

23.1 Boolean对象的方法

方法 描述 FF N IE
toSource() 代表对象的源代码 1 4 -
toString() 把逻辑值转换为字符串,并返回结果。 1 4 4
valueOf() 返回Boolean对象的原始值 1 4 4

24 JavaScript Math(算数)对象

  • JavaScript提供8种可被Math对象访问的算数值:
    含义 算数值
    常数 Math.E
    圆周率 Math.PI
    2的平方根 Math.SQRT2
    1/2的平方根 Math.SQRT12
    2的自然对数 Math.LN2
    10的自然对数 Math.LN10
    以2为底的e的对数 Math.LOG2E
    以10为底的e的对数 Math.LOG10E

25 JavaScript HTML DOM对象

25.1 HTML DOM对象

对象 描述
Window JavaScript层级中的顶层对象。Window对象表示浏览器窗口。
Navigator 包含客户端浏览器的信息。
Screen 包含客户端显示屏的信息。
History 包含了浏览器窗口访问过的 URL。
Location 包含了当前URL的信息。
 

旅行者网站框架完工

旅行者小网站的框架设计

这么一张图,从早晨十点一直写到晚上十点。主题就直接参考本博客了,清爽淡雅。只是实现的方式略有不同。

框架采用1-2-1单列变宽布局。参考《CSS设计彻底研究》14.1节的巧妙方法,自己调节参数,花费了约三、四个小时的时间。

菜单栏采用Mac风格色系,找了张图,Print Screen一下,用Gimp打开,用取色工具获得颜色的HTML代码表示,如下图:

Gimp取色工具

导航菜单栏有个动态的折叠功能,是纯CSS代码做成的,参考的是《CSS设计彻底研究》第9章的内容。不过还有些小bug,暂不展示了。

Footer加了几个小logo,也算给Gnu做个小广告,呵呵。

网站存在的主要问题在于兼容性。出于美观考虑,多数div采用了圆角设计。《CSS设计彻底研究》第11章专门讲圆角设计,虽然兼容性好,但是各种方法都很麻烦,不能随心所欲。于是就琢磨CSS有没有内置的圆角设计支持,万幸,我找到了这篇文章。这种设计在我的Firefox3.0+文泉驿Micro Hei字体下显示效果非常好。Chrome下也凑合,Opera 10中不能显示圆角效果,最差的是IE6,不但不支持圆角,动态的菜单也不支持。我没有IE7,没做测试。

今天这么一写,对CSS的选择特性、继承特性、层叠特性、div布局熟悉了很多。“纸上得来终觉浅,觉知此事要躬行”,一点没错啊。

明天开始整理网站内容。还有一周的时间,要抓紧了。

最后,把源码放上来吧^_^ 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
css yuanjiao
</title>
<style type="text/css">
body{
background-image: url(./images/main-bg.jpg);
background-repeat: no-repeat;
background-color: #3da9d7;
}

div{
border: 1px solid #dedede;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}

#header, #footer, #container{
margin:0 auto;
width:75%;
padding:0 0px;
}

#container{
border: 0px;
}

#header{
margin-bottom: 10px;
}

#content_wrap{
float:right;
margin-right:-150px;
width:100%;
border: 0px;
}

#content{
font-size: 0.8em;
border: 0px;
background-image: url(./images/sidebar_background.png);
padding: 5px 15px;
-moz-border-radius-topleft:0px;
-moz-border-radius-topright:0px;
-moz-border-radius-bottomleft:10px;
-moz-border-radius-bottomright:10px;
-webkit-border-top-left-radius:0px;
-webkit-border-top-right-radius:0px;
-webkit-border-bottom-left-radius:10px;
-webkit-border-bottom-right-radius:10px;
}

#content_wrap #menubar{
margin-right: 150px;
}

#content_wrap #content{
margin-right: 150px;
}

#menubar{
padding-left: 15px;
background-color: #e0e0e0;
border-width: 0px 1px;
-moz-border-radius-topleft: 10px;
-moz-border-radius-topright: 10px;
-moz-border-radius-bottomleft: 0px;
-moz-border-radius-bottomright: 0px;
-webkit-border-top-left-radius:10px;
-webkit-border-top-right-radius:10px;
-webkit-border-bottom-left-radius:0px;
-webkit-border-bottom-right-radius:0px;
}

#sidebar{
float:left;
width:140px;
border:0px;
}

#footer{
margin-top: 10px;
clear:both;
text-align:center;
}

#clear{
margin:0;
padding:0;
border:0;
clear:both;
}

#menubar a:link, a:visited{
color: black;
text-decoration: none;
}

#menubar a:hover{
color: white;
background-color: #09aee6;
text-decoration: underline;
}

#links, #navibar, #portrait{
margin: 0px 0px 5px;
border: 0px;
}

#header h1{
margin: 8px;
text-align: center;
color: #ffffff;
}

#header h3{
margin: 3px 15px;
text-align: right;
color: #ffffff;
}

#ul_menu{
margin: 0;
padding: 0px 15px;;
list-style-type: circle;
}

#ul_menu li dt{
margin: 0;
padding: 5px;
border-bottom: 1px dashed blue;
}

#ul_menu li dd{
font-size: 0.8em;
margin: 0px;
padding-left: 5px;
display: none;
}

#ul_menu li:hover dd{
display: block;
}

#ul_menu li dd a:hover, a:active{
color: #ffffff;
text-decoration: underline;
background-color: #09aee6;
}

</style>
</head>
<body>
<div id="header">
<h1>浙江大学旅行者户外运动俱乐部</h1>
<h3>行走、思考、在路上</h3>
</div>
<div id="container">
  <div id="content_wrap">
    <div id="menubar">
      <a href="#">Home</a>
      <a href="#">旅行者手册</a>
      <a href="#">酒吧</a>
      <a href="#" s>关于</a>
    </div>
    <div id="content">
      This is content;<br/>
      This is content;<br/>
      This is content;<br/>
    </div>
  </div>
  <div id="sidebar">
    <div id="portrait">
      <div id="menubar">
        行者无疆
      </div>
      <div id="content">
      <img src="./images/traverller_foot1.jpg"/>
      </div>
    </div>
    <div id="navibar">
      <div id="menubar">
        本站导航
      </div>
      <div id="content">
        <ul id="ul_menu">
          <li>
          <dl>
            <dt>旅行者说</dt>
            <dd>旅行者成立</dd>
            <dd>浴火永生</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>单车天涯</dt>
            <dd>进藏日记</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>骑行手记</dt>
            <dd>如何洗车</dd>
            <dd>爬坡要点</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>勇者竟攀</dt>
            <dd>攀岩知识</dt>
          </dl>
          </li>
          <li>
          <dl>
            <dt>驴行天下</dt>
            <dd>徒步攻略</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>行吟游唱</dt>
            <dd>骑马挎枪走天下</dd>
            <dd>旅行的意义</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>技术装备</dt>
            <dd>单车装备大全</dd>
            <dd>shimano系列介绍</dd>
            <dd>sram介绍</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>布袋事件</dt>
            <dd>布袋其人</dd>
            <dd>事情经过</dd>
            <dd>社会帮助</dd>
            <dd>布袋现状</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>医疗知识</dt>
            <dd>膝盖保养</dd>
            <dd>高原反应</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>户外资源</dt>
            <dd>网络资源</dd>
            <dd>杭州本地</dd>
            <dd>书籍资源</dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>会长感悟</dt>
            <dd>冻冻</dd>
            <dd>巫婆</dd>
            <dd>cnlox</dd>
          </dl>
          </li>  
        </ul>
      </div>
    </div>
    <div id="links">
      <div id="menubar">
        友情链接
      </div>
      <div id="content">
        <ul id="ul_menu">
          <li>
          <dl>
            <dt>校内资源</dt>
            <dd><a
              href="http://www.cc98.org/list.asp?boardid=147&page=1"
              target="_blank">
行者无疆</a></dd>
            <dd><a href="http://www.zju88.org/agent/board.do?name=Bicycle&mode=0&page=0" target="_blank">88Bicycle</a></dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>单车天下</dt>
            <dd><a href="http://www.chinabike.net" target="_blank">Chinabike</a></dd>
            <dd><a href="http://www.hzbike.com" target="_blank">骑行网hzbike</a></dd>
            <dd><a href="http://www.biketo.com" target="_blank">自行车旅行网</a></dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>徒步登山</dt>
            <dd><a href="http://www.8264.com" target="_blank">8264户外资料网</a></dd>
            <dd><a href="http://www.chinawalking.net.cn"
              target="_blank">
中国徒步网</a></dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>贴心工具</dt>
            <dd><a href="http://www.ctrip.com" target="_blank">携程旅行网</a></dd>
            <dd><a href="http://maps.google.cn" target="_blank">Google地图</a></dd>
            <dd><a href="http://shenghuo.google.cn/shenghuo/" target="_blank">Google生活</a></dd>
            <dd><a href="http://www.weather.com.cn/" target="_blank">天气预报</a></dd>
          </dl>
          </li>
          <li>
          <dl>
            <dt>友情合作</dt>
            <dd><a href="http://www.51outdoor.com" target="_blank">天择户外</a></dd>
            <dd><a href="http://www.lvyouzhi.com" target="_blank">旅游志</a></dd>
          </dl>
          </li>
        </ul>
      </div>
    </div>
  </div>
  <div id="clear">
  </div> 
</div>
<div id="footer">
  <a href="http://www.gnu.org/software/emacs/" target="_blank">
  <img src="./images/emacs_logo.jpg" width="32px"/>
  </a>
  <a href="http://www.ubuntu.org.cn/" target="_blank">
  <img src="./images/ubuntu_logo.jpg" width="32px"/>
  </a>
  <a href="http://www.mozillaonline.com/" target="_blank">
  <img src="./images/firefox_logo.jpg" width="32px"/>
  </a>
  <a href="http://www.w3china.org" target="_blank">
  <img src="./images/w3c_logo.jpg" width="32px"/>
  </a>
</div>

</body>
</html>

CSS设计彻底研究

非常不错的一本书。不同于一般书籍的说教式,这本书是由浅入深,边讲边实验,并结合CSS Zend Garden某些实例,深入分析,阅毕让人有种醍醐灌顶、恍然大悟的感觉。

CSS Zend Garden是个很神奇的网站,具体来说,这个网站展现了CSS应用的最高境界。同一份HTML文档,配上不同的CSS文件,上千幅精彩绝伦、风格迥异的作品。搞的我想去学设计,学色彩、建站,呵呵。

今天主要看了这本书的前六章,在原有的基础上对CSS有了进一步的了解,重点是CSS盒子模型、浮动定位,这本书的讲解让我大彻大悟。明天在仔细看一下某些特效的制作。套用一下,争取把旅行者手册的网站版框架给搞出来。打算采用1-2-1布局模型,配上淡蓝色的背景、类苹果风格的导航菜单栏,再在Footer中加上Gnu Emacs和Firefox等的小广告,呵呵。

感觉HTML、CSS和\LaTeXe的思想是一致的。都是内容和形式的分离。广义来说,这和Unix的哲学又是一致的。“大事变小,小事变了”,简单工具的组合,每种工具的专注,任务的分解。工具的组合。Keep It Simple, Stupid。伟大的Unix哲学。




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee