CoffeeCat's IT Blog

2009年6月29日

如何自定义file input控件的样式

    在上传文件的时候,一般会在表单中加入file input表单元素。这个控件的标准视图是一个文本框加上一个浏览按钮,如图:
   
   
    不过,有时为了美化页面,我们常常需要用图片来制作美观的浏览按钮,用户点击这张图片,可以弹出文件选择对话框。例如,开心网的网盘在上传文件时的页面

   

    开心网是用Flash实现的,因为它使用了类似swfupload的控件,可以带进度的上传文件。不过,如果我们不用Flash的话,是否可以实现呢?答案是肯定的。



实现思路

    我们可以将file input控件设置成完全透明,然后,加入一个自定义的浏览按钮,可以是图片。然后,我们定义这个按钮的onmousemove属性,捕获到鼠标移动到上面的时候,我们就将透明的file input控件盖在上面,这样,如果我们点击了,那将点击file input控件,就能弹出文件选择框了。由于file input是透明的,给用户的感觉就是点击了自定义图片而弹出的文件选择框。


关键代码

   
<input type="file" id="browse" size="1" style="position:absolute; width:0px; filter:alpha(opacity=0);-moz-opacity:0;" />  
<img src="upload.gif" onmousemove="document.getElementById('browse').style.top=(event.clientY-10)+'px';document.getElementById('browse').style.left= (event.clientX-30)+'px';" />

以上代码在IE7和Firefox3测试通过,页面上有1个美化的添加文件按钮,点击这个按钮会弹出文件选择框。


代码下载

http://www.cnitblog.com/Files/CoffeeCat/custom_upload.rar



Ferris Xu
2009-06-29



posted @ 2009-06-29 11:50 CoffeeCat 阅读(12) | 评论 (0)编辑 收藏

2009年5月8日

一个iframe不显示内容的原因

今天碰到个很离奇的问题:我有2个文件,内容是一样。我用Firefox打开,效果完全一样,用IE打开,发现其中1个网页的iframe的内容全部没有显示。

我用UltraEdit打开,对比了两个文件的文本,完全一样,然后我切换到16进制模式,再对比了一下,还是完全一样。这就奇怪了,两个完全一样的网页,怎么一个能正常显示,另一个却不能呢?

这两个文件肯定是有差别的,如果内容没有差别,那么就是文件名有差别了。不过从理论上来说,文件名有差别不会影响内容的显示啊。我试验了一下,问题依然存在。

难道是缓存的问题?试了一下,还是不行。

然后我把这两个文件分别复制了一份,命名为另外一个名字,问题还是存在。这个太离奇啦,完全一样的两个文件怎么显示的效果会不同呢?

总算,同事想到了还有一个可能存在差异的地方:那就是文件的属性。

于是,我看了两个文件的属性,果然,不能正常显示的那个文件的属性页里有这样一句话:“此文件来自其他计算机,可能被阻止以帮助保护该计算机”。点击解除锁定以后,再刷新一下浏览器,这下正常了。

至此,问题解决。这个问题虽然不常见,不过很典型,与大家分享。


Ferris
2009-05-08


posted @ 2009-05-08 09:39 CoffeeCat 阅读(203) | 评论 (2)编辑 收藏

2009年5月4日

浅谈SQL Update返回影响行数的意义

在大学的时候学习了JSP,其中使用JDBC进行数据库操作,有一个语句是Statement.ExecuteUpdate,这个语句执行一个SQL的更新操作(如delete,update,insert),返回所影响的行数。当返回0时,则表示没有更新任何行。我以为可以判断返回值是否大于0来判断更新是否成功,但是,下面的两种情况均返回0:

    1:没有找到需要更新的数据
       比如,我们进行update的时候,条件是id=5,但是id=5的数据不存在。这种情况下,更新是失败的,返回0,很正确。

    2:要更新的数据和更新的值是完全一样的
       比如,我们要对id=5的记录进行更新,把title变成hello。虽然这条记录存在,但是这条记录的title本来就是hello,那么,返回值也是0

 

这样就有个问题,当第2种情况发生时,从逻辑上讲,更新操作是成功的,你可以理解成title被重新覆盖了,不管它原来是不是hello,但是现在就被更新成hello了。

因此,如果要对Update进行是否更新成功的判断,就需要在Update之前,调用Statement.ExecuteQuery进行查询,如果能查询到记录,则表示更新会成功。ExecuteUpdate的返回值仅仅代表更新了多少行。

这样,一个Update操作就会执行2次SQL语句的,效率会降低。我当时就纳闷,为什么ExecuteUpdate对于第2种情况会不返回0,虽然从数据库的角度上,它是可以忽略更新这条记录,但是从逻辑的角度上看,这条记录被更新似乎更加合乎情理,返回大于0的值似乎更有意义。


不过,为什么基本上所有的编程语言,只要有类似的函数,都会在第2种情况返回0呢?


最近,这个问题总算想通了,之所以返回0,其实是为了解决同步的问题。

举个例子,现在,著名的开心网要对菜园的功能进行扩展,不光是能让玩家种菜,还要能让玩家偷别人家的菜。我们的程序逻辑如下:

 

某菜园:有成熟的菜N颗
A:     有偷来的菜0颗
===========================
A:     某菜园有多少颗成熟的菜?
某菜园:N
A:     偷1颗
某菜园:成熟的菜=N-1

A:     口袋里的菜
+1
===========================
某菜园:有成熟的菜N-1颗
A:     有偷来的菜1颗  

 

 

这段程序的逻辑没有任何问题。

好了,现在程序开始给玩家用了,有一颗超级无敌白金大青菜快成熟了,众玩家垂涎欲滴等着偷。成熟的那一刻,众玩家以瞬间的爆发力点击了鼠标左键,进行了偷菜。

假设有2个人A和B,几乎同时点击了鼠标,我们看服务器上程序的逻辑:


 

某菜园:有成熟的菜N颗
A:     有偷来的菜0颗
B:     有偷来的菜0颗

===========================
A:     某菜园有多少颗成熟的菜?
B:     某菜园有多少颗成熟的菜?
某菜园:N
某菜园:N
A:     偷过来
B:     偷过来
某菜园:成熟的菜=N-1

某菜园:成熟的菜=N-1

A:     口袋里的菜
+1
A:     口袋里的菜
+1
===========================
某菜园:有成熟的菜
N-1
A:     有偷来的菜1颗  
B:     有偷来的菜1颗  

 

 

大家可以看到,现在的超级无敌白金大青菜总数变成了N+1了,无故多出了1颗,显然,这个结果是不对的,也不是我们想要的。

开心网的代码是用PHP开发的,PHP中可没有Java中的Synchronous关键字。如果用一个本地文件来实现锁的功能,服务器的运行效率就会大大打折。那么,我们如何高效的解决这个同步问题呢?这时候,执行Update返回所影响的行数就具有了超人般的意义了。


 请看上面第2段中的粗体代码,在执行这个逻辑的时候,我们会得到的Update的返回值是0,因为在做这个操作之前,菜园里的蔬菜数量已经被更新成N-1了,所以这个更新操作会被忽略,这样,我们就可以在程序中加一个判断:如果更新的返回值是0,则表示偷菜失败,虽然Update是成功的。虽然B问菜园的时候是有菜的,但是偷的时候却没有了,那也表示B没有偷到。

可见,返回所影响的行数是非常有意义的,对于并发量大的网站,可以好好利用这个返回值,能在保证效率的状态下,解决同步的问题。



Ferris
2009-05-04

posted @ 2009-05-04 18:30 CoffeeCat 阅读(165) | 评论 (0)编辑 收藏

2009年4月30日

ASP出现Disallowed Parent Path的一个解决方法

问题描述:
    <!--#include File "../int/conn.asp"-->代码出现ASP运行错误,提示Disallowed Parent Path,原因是脚本所在的服务器不支持父目录寻址,这个问题在Apache支持ASP的Web服务器中比较常见。


解决方法:
     我们可以使用include Virtual来代替include File。include Virtual后面跟的是相对于网站跟目录的路径,不是相对与当前文件的路径。例如:我们的站点目录如下:


其中,WebApp是站点根目录,inc目录下有conn.asp,lib下有test.asp,原先,在test.asp中是使用以下代码来包含conn.asp的
<!--#include File "../inc/test.asp"-->

现在,修改成
<!--#include Virtual "inc/test.asp"-->

这样就可以解决那个运行错误了


Ferris
2009年04月30日

posted @ 2009-04-30 15:14 CoffeeCat 阅读(47) | 评论 (0)编辑 收藏

2009年4月23日

在PHP中实现类似Javascript的事件模型

     摘要:     Javascript在处理事件的时候,使用了观察者模式,使得发生事件的对象和响应事件的对象完全的解耦,提高了系统的可扩展性。例如: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->var myListe...  阅读全文

posted @ 2009-04-23 10:56 CoffeeCat 阅读(39) | 评论 (0)编辑 收藏

2009年4月21日

PHP回调函数的实现方法

     摘要: 目录      前言      全局函数的回调      类静态函数的回调      对象的方法的回调      PHP事件模型(...  阅读全文

posted @ 2009-04-21 16:52 CoffeeCat 阅读(146) | 评论 (0)编辑 收藏

2008年12月15日

解决PHP中的Cannot modify header information的问题

写PHP的朋友们肯定遇到过这样一个问题:通过header函数改变http协议头的时候,会出现一个类似下面格式的warning:
Warning: Cannot modify header information - headers already sent by

这是为什么呢?因为在使用header函数之前,您不能输出任何东西,包括用echo或var_dump等输出函数的输出,还有在<?php之前的空格。不过有的时候,我们并没有输出任何东西,却还是会出现这个错误,这是因为我们的文件包含了BOM签名,我们必须把它去掉。下面我们就来讨论这个问题。

请看测试代码:

<?php
header("content-type:text/html;charset=utf-8");
die();
?>

    这段代码就是简单的header一下,在<?php之前也没有任何输出,也没有空格,但是网页里还是提示了Cannot modify header information的警告信息。这说明,在<?php之前还有内容,只是编辑器没有显示出来。
    我们用ultraEdit打开这个文件,切换到16进制,可以看到,在文本的开头,有EFBBBF,之后才是3C 3F 70 68 70 ( <?php ),说明,在<?php之前,确实存在着输出信息,因此,在修改header的时候,会得到警告信息。




    这个EFBBBF是什么东西呢?它的名字叫BOM,Byte Order Mark,是在Windows下的一个约定,用于标记文本是否是Unicode。记事本程序就是通过这三个字节来判断文件是ANSI还是Unicode。

    知道了问题发生的原因,下面,我们想办法把BOM去掉。用Dreamweaver打开这个php页面,然后进入页面设置(按Ctrl+J),弹出以下窗口:
   

取消选择“包括Unicode签名(BOM)”,确定就可以了。现在,我们再用UltraEdit打开看这个文件的16进制内容,如下图



可以看到,现在BOM信息已经没有了,文件直接以3C3F70开头了。

最后,我们刷新一下浏览器,发现现在已经没有Warning提示了,问题解决。




Ferris
2008-12-15

posted @ 2008-12-15 12:48 CoffeeCat 阅读(176) | 评论 (0)编辑 收藏

2008年12月10日

在Javascript中给变量赋多行字符串的方法

    今天写JS的时候,遇到一个需求,我需要将一个文本文件的内容作为一个字符串赋值给一个变量,这个文本文件是多行的。首先,我想到了,将文本文件中的所有换行符替换成\n,将所有双引号替换成\",这样就可以将这个多行文本转换成单行文本了。不过,如果JS有类似于PHP的字符串定界符的话,就更好了。于是,在网上搜索了一下,找到了两个方法


我的文本文件内容:
Line1
Line2Line2
Line3


方法一(支持Firefox)

     这个方法的原理是生成一个XML节点。因为XML可以使用CDATA来生成多行文本。然后,再将这个节点转换成字符串,就可以得到一个多行文本了。不过这个方法只在支持E4X的浏览器上有效。经过测试,Firefox3.0支持,IE7.0不支持。

代码如下:

var str = (<r><![CDATA[
Line1
Line2Line2
Line3
]]
></r>).toString();

alert(str);


方法二(支持IE)

     这个方法相当有创意,是网络上某个高人的杰作。
     方法的原理是将多行文本写在一个函数体的多行注释内,然后,通过字符串解析函数,将多行文本分离出来,这样,整个文件内容也可以原封不动的复制到JS代码中。不过这个方法只在IE里支持,Firefox会将注释代码从函数体中移除。

Function.prototype.getMultiline = function() 

    
var lines = new String(this);  
    lines 
= lines.substring(lines.indexOf("/*\r\n"+ 4, lines.lastIndexOf("*/"));  
    
return lines; 
}   
var str = function() {  
/*
Line1
Line2Line2
Line3
*/
}.getMultiline();

alert(str);




Ferris
2008-12-10

posted @ 2008-12-10 11:03 CoffeeCat 阅读(328) | 评论 (0)编辑 收藏

2008年9月14日

我的千千静听网页版发布了

千千静听网页版(FXPlayer 0.4 测试版)


版本信息
    * 作者 - Ferris Xu
    * 版本号 - 0.4 测试版
    * 更新时间 - 2008年02月01日
    * 兼容的浏览器:IE,Firefox 2.x

特点
    * 纯Javascript的实现,无需任何第3方的JS框架)
    * 面向对象的架构设计,自定义播放器事件
    * 自定义UI组件,可拖动,缩放窗口
    * 兼容IE和Firefox2.x
    * 提供了音量,进度等控制,界面和千千静听完全一致
    * 兼容千千静听5.0的播放列表,基本兼容千千静听的皮肤,能在播放时切换皮肤
    * 播放时动态歌词的显示

说明
    * 本程序仅用于演示,以及Javascript技术的学习和交流,不会进行任何商业行为。
    * 由于时间的关系,本程序在播放列表功能上没有全部完成。
    * 由于千千静听的皮肤是一个压缩包,并且里面的图片都是BMP的,在网页上无法使用,所以本程序所兼容的是已经解压缩的,并且将所有图片都转换成网页格式的图片(如gif)。
    * 由于Firefox3在WMP插件的事件捕捉上存在Bug,因此本程序不能在Firefox3上面正确运行
    * 处于对千千静听的喜爱,我开发了它的JS版本,并取名为千千静听网页版。若有不妥,请告知,谢谢。


效果截图



演示地址
http://www.CoffeeCat.net.cn/web/fxplayer

程序下载
http://www.cnitblog.com/Files/CoffeeCat/fxplayer0.4.rar

posted @ 2008-09-14 22:26 CoffeeCat 阅读(310) | 评论 (0)编辑 收藏

2008年9月2日

一个在IE中报语法错误但在Firefox下却能正常运行的JS范例

最近在写一个JS程序,遇到这样一个问题,请看代码:

var myobject = {};
myobject.
delete = function()
{
    alert (
"call delete");
};
myobject.
delete();


    这段代码从思想上没有任何问题,定义1个对象myobject,并且给它一个删除的方法名为delete,最后调用delete方法。这段代码在Firefox下能正常运行,但在IE下却报语法错误。原因相信大家也发现了,IE把delete看成是关键字了,而Firefox会把delete看成是myobject对象里的一个方法。所以,把delete方法改名字就对了,以后尽量不要用JS关键字做方法名,如new,delete等

    因此,如果您在写JS程序时,遇到Firefox正常,但IE报语法错误,通常情况下,都是您使用了delete或者new关键字定义了方法名,您可以从这方面下手debug。

    最后聊点题外话,介绍一下JS在Firefox以及IE下的调试工具。Firefox下就不说了,有大名鼎鼎的Firebug,这款工具不仅查看DOM结构,JS错误信息等,最重要的它能够监视网络的数据。IE下的调试工具也不少,微软的IE Developer Toolbar和Firebug挺类似的,只是它没有监视网络数据的功能,这对调试Ajax代码比较不好。调试JS的工具我觉得最好的是Companion JS,我觉得它是IE下最好的JS调试工具,它能够准确定位到出错的JS代码,而且它是免费的。如果没有Companion,我可能需要更多的时间才能找到罪魁祸首delete的。另外,Firebug也有IE版的,不过IE版的Firebug是完全用JS写的,处理速度十分缓慢,特别是分析DOM树、分析CSS等,速度奇慢,缺少实用性,而且Firebug for IE不能检测网络数据。



Ferris
2008-09-02

posted @ 2008-09-02 15:26 CoffeeCat 阅读(357) | 评论 (0)编辑 收藏

仅列出标题  下一页
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

公告

常用链接

留言簿(28)

随笔档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜