CSS学习之综合运用
以前我也用CSS,不过只是很简单地用它来控制字体大小、链接样式,表格边框而已。要说页面布局和排版,我从来没想过用CSS,毕竟我用表格可以算得上是滚瓜烂熟了,表格+少许CSS,我已经能够实现所有需要的效果了。
直到最近DIV+CSS布局的页面开始成为潮流,我看了一些网站,总体感觉还是不如表格的漂亮。可是当去除CSS以后,看看人家的内容仍然整整齐齐地显示在页面上,而且很少有多余的东西,再看看一个页面里去除了那许多的表格和字体代码后,结构清晰的源代码,我才真正理解很多书上讲的CSS的优点。
买了一本《CSS权威指南》来看,顺便在正在改版的学校网站上“学以致用”,今天为止,不能说熟练掌握,不过总算是基本上掌握了CSS的使用。做了一个融合字体、背景、布局、定位等的例子,算是对自己这段时间学习的总结。
这个标题部分,如果用表格,至少需要两行一共5个单元格。我用了下面的代码来实现:
<div class="redtitlebox" style="WIDTH: 300px">
<div class="redtitleleft"></div>
<div class="redtitlemain">热门图文</div>
<div class="redtitleright"></div>
<div class="redtitlerightbody" style="WIDTH: 185px">专题:</div>
</div>
对应的CSS规则:
.redtitlebox {
width:100%;
position:static;
border-bottom:2px solid #900;
margin:0px;padding:0px; }
.redtitleleft {
width:8px;
background:url(skin/oldbisu/redtitlebg_left.gif) no-repeat;
float:left;
height:20px;
line-height:20px;
margin:0px;
font-size:0px;
color: #FFF;
}
.redtitleright {
width:7px;
background:url(skin/oldbisu/redtitlebg_right.gif) no-repeat;
float:left;
height:20px;
line-height:20px;
margin:0px;
font-size:0px;
color: #FFF;
}
.redtitlemain {
width:100px;
text-align:center;
background:url(skin/oldbisu/redtitlebg_main.gif) repeat-x;
float:left;
height:20px;
line-height:20px;
margin:0px;
font-weight: bold;
color: #fff;
font-size: 12px;
}
.redtitlerightbody {
max-width:645px !important;
float:right;
height:20px;
line-height:20px;
background:url(skin/oldbisu/titlebg.gif) repeat-x;
margin-bottom:0px;
color: #666;
font-size: 12px;
text-align:right;
}
如果只是为了实现一个效果,似乎这个过程比用表格来实现还复杂了,但是考虑到这个效果将被运用在几千个网页里,就会觉得非常划算了。CSS毕竟只需要下载一次,而且这里还有我本身的问题,写CSS的经验还不够丰富,所以上面的样式规则肯定难免有一些冗余的地方。
总之,用CSS做网页的感觉,真的是很不错的……
被切断通讯的感觉
下午下了班,急着回家,因为已经月末了,一直还没空去交电话费。赶紧回家上网交了去。
回家把本子插好,开机的时候,突然看见电话的屏幕上有行奇怪的字,没看明白是什么。拿起电话听了一下,怪哦,什么声音都没有……
我那个电话是比较破的,朋友送的。平时通话质量就不太好。我想都没想就断定是电话出问题了,把线都重新插了一下,再试……还不行。
半个小时后,利用修电脑常用的“替换法”,我已经把电话线、电话机、分线盒……每个部件的出问题可能性都排除了。颓废地想:算了,还是上先上网吧,给网通公司发个Email问问……
然后发现:网也上不了……
不能打电话、不能接电话、不能上网……天哪,这是什么世界啊?
对着电脑无奈了,最后只好拿手机给网通打电话——这让我发现了中国的通讯运营商的又一个狠招:当你的固定电话无恙的时候,你可以拨打免费的网通或者电信的服务电话;当你的手机无恙的时候,你可以拨打免费的移动或者联通的电话;可是当你的手机出问题(比如我前两天充值后很长时间不能开机),你就只能用固定电话打收费的移动服务号码;而当你的座机出问题的时候,你又只能用手机打收费的固定电话服务号!而且这时候你会发现世界上最难打的电话号码是什么。
网通说:我们马上帮您查一下问题,很快会和您联系的……
网通的很快一直持续到第二天下午我写这个日志的时候,中间我还给网通又打过一个电话,回答如上。
被切断通讯的时间里,我玩单机游戏,写CSS,写文章……
总会突然想起来今天应该给某地的某某同志发的Email还没发;或者答应帮某网站的某某同志弄的东西还没给对方,然后就会下意识地开QQ;然后下意识地想打电话告诉对方我上不了网……
这种折磨持续了没有太久就消失了,我最终因为不堪忍受,抱着一本纸质教程睡着了……
看不见的敌人
今天看了一部老片《The Bunker》,因为要帮朋友写一篇作业。看了之后感觉还可以。
第二次世界大战作为人类历史上影响最为深远的事件,持续时间之长,涉及范围之广,为战后的文艺创作提供了取之不尽用之不竭的题材。
战争的残酷无情,人类生命的脆弱,生死存亡之际的人性……没有什么别的事件,更易于表达这些主题。美国电影《碉堡》(The Bunker),正是一部以第二次世界大战为背景,试图探索和表现导演对人类本性、心理等问题观点的作品。
电影讲述了德国战败前夕,一队德国士兵逃到德国与比利时交界地区的一座森林,藏入一座碉堡,试图在这里做最后挣扎,最终他们没有被敌人攻陷或者俘虏,却被他们自己打败,几乎全军覆没的故事。导演通过设置悬念,充分利用各种矛盾冲突的演化和发展,逐步推进电影的情节,直到所有的矛盾冲突都积累到最高点,也是电影的情节的高潮时,顺理成章地将电影里的角色们推向他们早已注定的结局。
这部电影虽然以世界大战为背景,但是在影片中却没有太多双方交战的场面,实际上,影片一直到电影的最后,才出现了另一方。而在长达一小时多的主要部分,七名德国士兵一直在和“看不见的敌人”——他们自己心里的恐惧、猜忌作战。在电影的最开始,显示了尼采的一句名言——“当你凝视着深渊的时候,深渊也在凝视着你”(If you gaze for a long into an abyss, the abyss gazes also to you.),这应该就是导演希望通过这部影片表现的主题。而尼采的这句话,还有一半是“当你和魔鬼搏斗的时候,你也是魔鬼”。 阅读全文
动网的blog和动易的html
动网的论坛程序,在国内真的是影响深远,不仅使用的网站多,而且在ASP技术普及、交流方面也贡献不小,我接触ASP,就是从动网论坛开始的,动网现在的开发支柱——迷城浪子,据他自己说也是这样。从学习动网源代码开始,到掌握了ASP技术后分析、修改,到成为独当一面的ASP技术员,应该还有不少人走过这样的一条道路。
动网似乎一直是国内ASP技术的领头羊,很多现在被国内ASP程序普遍使用的手段,往往最早都是在动网论坛程序上开始运用,它不一定做得最好,但是它在新技术的运用上,从不后人。直到现在似乎还是,DIV+CSS布局,XML+XSLT输出……
但是在博客的问题上,动网不但落后了,而且几乎是完全被甩开了。动网Boke的1.0版本,随着动网的7.1而下载到无数站长的空间里。但是在互联网上,使用动网Boke的网站少得可怜。其实不怪站长们多此一举要到处去找别的博客程序并费尽心机地整合啊,修改啊。其实用动网论坛又想做博客网站的站长肯定都希望用动网boke来做,问题是动网根本没有博客程序,动网boke充其量是一个模仿博客的个人文集插件而已。除了RSS以外,它不具备任何博客的特征,连限制于站内的Trackback都没有。
当然我们不知道动网真正要做的是什么,多人博客系统 or 动网论坛的个人文集插件。如果是前者,那动网boke真的是目前我所接触过的blog程序里最糟糕的一个。如果是后者,那它真的可以算是一个非常经典的而且最好的动网插件了。
与此类似,动易也有一样的问题,动易的系统简单易用,功能强大,在对模版功能要求很高的CMS系统里,动易系统几乎所有页面都可以定制模板(另一种说法是几乎所有页面都只能),而又不过于复杂。在没有人关注WEB新标准的时候,动易真的很人性化。
但是对于希望构建符合WEB新标准的网站的站长来说,则是另一种情况。动易目前还不支持WEB新标准,不仅程序自身不支持,而且它不让你支持。
你可以尝试在Dreamweaver8.0中制作一个代码非常规范的网页,把源代码粘贴到动易的模版编辑器中,然后保存,再编辑它——你发现,你的很规范的代码,现在已经不规范了,属性值的引号被自动去掉了,小写的HTML标签有的被替换为大写,有的被替换为首字母大写……
动易的团队相比一年多以前,已经强大了很多倍,动易的功能模块也已经趋于成熟。这个时候,动易在运用新技术,增强功能之外,应该将适当的精力投向市场,看看现在的互联网上的潮流和趋势。也许我们认为新标准不重要,或者我们认为支持新规范不如增加新功能更重要,但是要看到越来越多的站长开始重视、追求这个,如果我们的产品不符合他们的需要,他们就会转向别的提供商,别的产品。
无论对于动网,还是动易,在做到了、或者接近了同类产品中的领先地位的时候,还要做技术的领头羊,带领行业的发展,而不是等着到了没有它不行的时候,才去运用某项技术。不是要等着网络的发展趋势来敲自己的屁股,而是时刻关注最前沿的咨询,并在涉足的行业内,引领着大家向那种趋势前进。
以动网和动易的技术实力,我相信所有上述的这些问题,都只是理念和认识上的问题,因为从技术的角度讲,这些暂时存在的缺点,都不足以对他们形成障碍。
动网和动易都计划在下一版本的程序中做出重大的改动,希望会让我们有惊喜!
为我的blog写的Google地图生成器
好长时间没用ASP开发了,今天用Div+CSS重构学校的官方网站,做得头晕,回到家突然想起来给自己的blog做一个google的站点地图生成程序,就动手了。
这个东西很简单,google地图是规范的XML文件,只要按照Google说明的格式把网址都列出来就可以了。因为我的blog重新做以后内容还少,Google说一个地图文件可以容纳50000个索引,按照每天新增一篇日至计算的话,还要100多年以后我的地图才会超出标准,所以我就没有打算做地图索引,直接用一个文件做地图了。
这个小程序大约花了一个小时写完的,中间还跟朋友聊天,吃宵夜了
生成的地图包括blog分类和每篇blog的地址,这里需要注意的是PJblog支持生成asp文件的方式来保存blog,所以提交给Google的最好是固定地址,也就是不是article.asp?id=xxx这样的,而是default.asp?id=xxx这样的。
我给分类地址都做了更新频率和重要性的标记,分类的地址设定为每日更新(因为我是每天写一篇日志),重要性设置为1,非blog分类的其它模块设置重要性为0.5,而blog就只提供地址。
因为是针对自己的站点写的,所以我没有对这个程序做太多完善,够我用就行了。如果有用PJblog的朋友感兴趣的话,可以下载附件的txt文件,那个就是完整源代码。
ASP中的数字和字符比较
昨晚和老迷聊天聊到很晚,说到一个把字符串转换为数字进行比较的问题。老迷说他喜欢保持字符串本身的类型,进行字符串的匹配比较,而不喜欢把字符串强制转换为数字进行比较。
一开始我不太明白这到底有什么区别,比如
a = “1″
If a = 1 Then
'Something
End If
和
a = “1″
If a = “1″ Then
'Something
End If
在VB中,变量的数据类型默认是Variant,在必要的时候自动转换,例如上例第一种,由于表达式右边是数字,因此系统会自动将字符串变量a转换为数字类型,然后进行数字的比较。而第二种则没有转换类型这个过程。
这个从代码上看没有任何区别的比较过程,在执行时却差着一个步骤。这就是老迷关于他为什么更愿意保持字符串变量的字符串类型来进行比较的原因。
最简单的运用就是用户登录时,比如有个是否保存cookies的选项。通常是用下拉选择或者单选按钮,表单数据经过ASP程序读取之后,Request.Form(”cookies”)的值默认情况下是字符串类型的。我们往往是把它当成数字来用,有时候我们还习惯用 a = Cint(Request.Form(”cookies”))的方式在读取时进行转换,也或者不做转换,直接用 If a = 1 来判断。
实际上不管用哪种方法,都离不开一个转换的过程,而且为了避免 Cint 函数出错,我们往往还需要在前面增加一个IsNumeric的验证,这样一来,多出来的就不只是一个步骤了。
而如果我们直接把Request.Form(”cookies”)作为字符串考虑,我们只需要一行代码即可:
If Request.Form(”cookies”) <> “” and a = “1″ Then
就同时完成了数据有效性验证和比较。
这个很小的细节,在实际编程中用到的地方非常多,每个地方都多两个步骤,那的确在性能上就是比较低大的浪费了。
《世界大战》
昨天晚上回来的时候已经感觉很累了,又有朋友在宿舍玩,就翻碟来看。好久都没去买DVD了,找出一张前几天买的《世界大战》,一直听说,不过买来就一直没看,就放了看了。
总的感觉一般,我们不是专业的影评人,对于拍摄啊,演员的表现啊都没什么发言权。不过作为老看电影的观众,对这部片子的感觉就是一般。 阅读全文
ASP.NET2.0快速入门站点
最近没有关注微软的MSDN,今天在思迈博客看到消息才知道ASP.NET2.0的快速入门站点已经开放了。
微软似乎越来越喜欢MSDN那样的风格了,不过2.0的快速入门的确比1.1时候的要看起来舒服得多。
目前还没有中文版,英文版的地址如下:
http://beta.asp.net/QuickStart/default.aspx
关于动易整合的个人想法
整合,是软件开发领域的一个新的热点和发展趋势。基于C/S架构的网络运用程序正在向B/S架构过渡或者被B/S架构的软件所代替。相比之下,论坛啊,商城啊之类的整合都已经是小菜了,专家们思考的是怎样实现不同平台、不同系统、不同程序语言和数据库之间的信息查询、数据交换、身份认证等等。
动易系统从第一个版本开始就把自己拴死在动网论坛身上,从最早的数据库整合,到后来的Cookies整合,一直到2005版的通信证整合,尽管是越来越摆脱动网程序的限制,但是说到底还是动易去和目标程序整合。要想办法实现目标程序的注册、登陆、注销等等一系列的问题。
一个程序的整合就需要那么多手续步骤,要想真正做到兼容尽可能多的程序,谈何容易。而且整合的程序越多,有可能出现的密码不同、ID冲突等等问题就越多。
其实从其它领域的整合思路和实践我们应该能够得到更好的启示。
现在针对整合的问题,人们的思路似乎正在开始走向统一,那就是 WEB Service,既然是网络,TCP/IP协议和HTTP就是最佳的工具和手段。XMLHTTP,SOAP…越来越多而且越来越成熟的技术让为互联互通而头疼不已的程序员们看到了曙光。
动易似乎也应该转变一下思路,从主动地去实现与某个或多个程序的整合,转向提供一个标准化的请求和响应接口。无论任何程序,都可以按照规范向动易的接口提出标准化的查询请求,然后动易返回同样标准化的响应。至于其它的事,动易不要去管。
这一点,在博客的Trackback Ping技术上我们应该得到很好的启示。
你提供必须的信息,然后我告诉你你想知道的东西。就这么简单。更具体地说,两个程序间的信息交换,其实不应该超越必要的范围。一个程序向另一个程序提供用户名和密码,邮箱等用户的基本信息,然后收到该用户在对方是否存在,信息是否正确,可以获得什么样的服务和权限等信息,就像我们向一些机构提交一个身份证号码,然后对方告诉我们这个身份证号码是否真实这样的过程一样。
这样做最至关重要的一点是:每个程序相互不会干涉对方的事务,因此就不存在安全的问题。而且每个程序都拥有了更多的自主权。你告诉我这个用户在你那里是合法的,拥有多大的权限,而我下一步要怎样做,我可以自己决定。
通过XMLHTTP或者其它技术,这个过程可以很轻松地实现。
但是接下来的问题仍然存在:对于动易的用户而言,我只会对动易不断地提出各种各样的要求;而其它的WEB程序是否愿意接受动易的这个标准并在自己的开发中提供相关的支持,尽管对它而言这不会有什么坏处,而且能给它的用户更多选择的权利。但是如果它不肯,你的确是毫无办法。那等于用户的问题还是没有得到解决。
这个问题的关键在于:动易到底有多牛!
如果搜狐说必须有网站地图它才收录一个网站,相信很多站长会置之不理,但是如果google这样说,相信绝大部分的网站会特地去制作一个网站地图。
道理其实就这么简单。
用ASP为blog程序编写Trackback功能
作为所谓的Blog三大特征之一的Trackback Ping,在网络上并没有一个真正的规范,它实际上最早是在Moveable发明并开始运用的一种技术,与另外两项被广泛认为是Blog最主要特征的RSS和Permalink相比,RSS本质上是是一种遵循W3C RDF规范的XML格式,Permalink是一种非常通用的静态地址技术,而Trackback Ping目前为止仅仅是在blog程序中得到运用,除了Moveable的一份技术规范文档外,也没有什么权威的标准,尤其在国内,众多blog程序有的支持有的不支持,有的有限支持,甚至还有因标准不一致而不能互相通信的(参见《blog is dead(blog已死)》)。
但是作为开发人员,我们不需要去讨论或者争论Trackback是不是死了、它会不会带来恶意Spam这些问题,就像垃圾邮件的存在,并不影响电子邮件的技术进步和使用一样。对于开发人员来讲,既然Trackback被认为是Blog的三大技术之一,而且blog程序的用户有这种需求,那我们在开发blog的时候,就应该包含这项技术。而且,我们应该尽可能地使我们开发的技术符合标准,或者规范,至少让它发挥作用。
Trackback Ping是由Moveable Type发明的规范,那么在没有更权威的标准之前,我们使用这项技术,当然应该以他们的规范为准,这里是他们的Trackback技术规范文档:http://www.movabletype.org/docs/mttrackback.html。
Trackback的完整实现至少包含两个方面,其一:客户端发送Trackback Ping;其二:服务器端接收和处理Trackback Ping,并向客户端返回处理结果。然后,根据需要我们可以考虑在客户端接收或者不接收,处理或者不处理返回的信息。下面是具体的代码:
'#函数名:Trackback
'#作 用:向指定的URL发送Trackback Ping,并根据服务器端返回的信息,提示用户处理情况。
'#参 数:
'#RemoteURL = 目标URL,也即所引用的blog所提供的引用地址
'#MyBlogURL = 我的Blog的URL
'#MyBlogName = 我的blog站点名称
'#MyBlogTitle = 当前这篇blog的标题
'#MyBlogExcerpt = 当前这篇blog的摘要
'#返回结果:字符串,以“|”分隔,第一部分为数字,0表示成功,1表示有错;第二部分是具体信息。
[code]
Function Trackback(RemoteURL,MyBlogURL,MyBlogName,MyBlogTitle,MyBlogExcerpt)
Dim objXMLHttp,objXML,intStat,strMessage,strPostInfo
'对参数进行必要的处理,比如URLEncode之类
MyBlogURL = Server.URLEncode(MyBlogURL)
MyBlogName = Server.URLEncode(MyBlogName)
MyBlogTitle = Server.URLEncode(MyBlogTitle)
MyBlogExcerpt = Server.URLEncode(MyBlogExcerpt)
'构造要发送的请求内容
strPostInfo = "title=" & MyBlogTitle
strPostInfo = strPostInfo & "&url=" & MyBlogURL
strPostInfo = strPostInfo & "&excerpt=" & MyBlogExcerpt
strPostInfo = strPostInfo & "&blog_name=" & MyBlogName
'创建对象
Set objXMLHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
Set objXML = Server.CreateObject("Microsoft.XMLDOM")
'以post方式打开XMLHTTP对象
objXMLHttp.Open "POST", RemoteURL, false
'发送请求内容,判断发送情况,并进行处理
On Error Resume Next
objXMLHttp.Send strPostInfo
If Err.Number <> 0 Then
Trackback = "1|TrackBack错误:无法连接服务器"
Else
If (objXMLHttp.readyState <> 4) or (objXMLHttp.Status <> 200) Then
objXMLHttp.Abort Trackback = "1|Trackback超时"
Else
objXML.async = false
objXML.load(objXMLHttp.responseXML)
If objXML.parseError.errorCode <> 0 Then
Trackback = "1|TrackBack响应解析错误"
Else
If objXML.getElementsByTagName("error")(0).Text="0" Then
Trackback = "0|Trackback成功"
Else
Trackback = "1|Trackback错误:"&objXML.getElementsByTagName("message")(0).Text
End If
End If
End If
End If
'释放对象
Set objXMLHTTP = Nothing
Set objDom = Nothing
End Function
[/code]
'#过程名:DealRequest
'#作 用:接收和处理客户端发来的Trackback Ping
'#参 数:无
[code]
Sub DealRequest()
Dim blog_id,tbTitle,tbName,tbURL,tbExcerpt,stat
'从所请求的URL中提取所引用的blogID,以便从数据库中检索对应的blog
'这个参数根据你所写的blog程序提供的Trackback地址形式而定
'这里我们假设这个参数为“id”
blog_id = Request.QueryString("id")
'读取出客户端传来的请求中的每个部分
'注意,这里没有对以Get方式提交的请求作出处理
'因为2003年以后根据技术规范已经不再接受Get方式的请求
'如果希望增强兼容性,可以加上对Get方式的请求的处理
tbTitle = Request.Form("title")
tbName = Request.Form("blog_name")
tbURL = Request.Form("url")
tbExcerpt = Request.Form("excerpt")
'检索数据库中id为blog_id的blog数据和url为tbURL的Trackback记录
'如果blog不存在,或者Trackback记录已存在,向客户端返回相应的出错说明
'我们这里调用一个进程tbResponseXML来完成这项工作
'调用时,以参数stat=0[1,2]分别表示成功、日志不存在和记录已存在
tbResponseXML(stat,"utf-8")
'如果是成功,还应当做好更新TrackBack记录和相关blog引用数的工作
End Sub
[/code]
'#过程名:tbResponseXML
'#作 用:接收和处理客户端发来的Trackback Ping
'#参 数:
'#stat:错误代码,0=成功;1=日志不存在;2=Trackback记录已存在
'#strCharset:要返回的XML的编码
[code]
Sub tbResponseXML(stat,strCharset)
Response.ContentType = "text/xml"
Response.Charset = strCharset
Response.Write "<?xml version=""1.0" encoding=""" & strCharset & """?>"
Response.Write "<error>
If stat = 1 Then
Response.Write "<message>
ElseIf stat = 2 Then
Response.Write "<message>You can not Trackback a blog twice from the same URL.</message>"
End If
End Sub
[/code]


