一劳永逸的 Editplus 配置

用习惯了 Editplus , 经常会做一些个性化的设置, 不仅让自己用得更顺手提高了工作效率, 也让自己节省了不少精力. 怎样才能让这些有用的配置不会因为重装系统而丢失呢?

默认情况下 Editplus 的配置文件(*.ini) 和 语法完成方成(*.acp) 以及语法着色文件(*.stx) 都是放在 Editplus 的安装目录下的. 要将它们分离出来做备份还是挺麻烦的.

还好聪明的 Editplus 给我们提供了一个有用的功能: 菜单->"工具"->"设置目录", 我们可以自定义 配置文件目录以及语法/着色/模版文件目录 的位置. 这样就可能在我们重新安装 Editplus 后将配置目录设置成我们自定义的目录就可以啦.

赶紧动手设置吧:
这里是我自用的配置文件: 下载

0, 假设我们 Editplus 的安装目录是:
   D:\Program Files\EditPlus 3\editplus.exe

1, 我们在安装目录外任意位置建好配置文件目录, 目录结构看上去像这样子:
   F:\software\editplus_config\
   F:\software\editplus_config\editplus_conf_1\
   F:\software\editplus_config\editplus_conf_2\
   F:\software\editplus_config\editplus_conf_ini\

   为什么会有 editplus_conf_1 和 editplus_conf_2 两个配置目录呢?
   因为我们可能会经常会遇到这样的情况:
   在我们在项目1中代码规范是这样子的
   function abc ()
   {
   }
   但在我们在项目2中代码规范是这样子的
   function abc () {
   }
   当我们经常在项目1和项目2中切换编写代码时, 我们设置的两个配置目录就可以派上用场啦,
   我们将项目1的语法文件放在 editplus_conf_1 目录中;
   我们将项目2的语法文件放在 editplus_conf_2 目录中;
   两个项目切换的时候只要修改一下 Editplus 的语法文件目录, 然后重新启动一下 Editplus 就OK啦.

2, 我们将 D:\Program Files\EditPlus 3\*.ini
   复制到 F:\software\editplus_config\editplus_conf_ini\

   我们将 D:\Program Files\EditPlus 3\*.stx, *.acp, template.*
   复制到 F:\software\editplus_config\editplus_conf_1\

3, 打开 Editplus 菜单->"工具"->"设置目录"
   将 ini 文件目录设置为 F:\software\editplus_config\editplus_conf_ini\
   将语法文件目录设置为 F:\software\editplus_config\editplus_conf_1\ 

4, 重启 Editplus , 新的配置目录就生效啦.

这样的方法可以将你的配置文件随身带着走啦~方便吧~~

应该注意的一些细节

设置好配置目录后, 有一个细节要注意一下:
打开 Editplus 菜单->"工具"->"参数"->"设置与语法" , 选择 "文件类型" 中的不同文件类型, 在下方的 "设置与语法" 页签中会有 "语法文件"/"自动完成" 两项, 注意: 这两项中都不能填写绝对路径 (带有盘符的路径), 只能填写相对应的配置文件名.

小技巧

EditPlus 集成 SVN  http://www.toplee.com/blog/615.html
1, 下载 sliksvn , 下载地址: http://www.sliksvn.com/en/download/
2, 将 tool.ini 存放在editplus的安装目录下
3, 启动editplus,CTRL+1 即可方便的提交
Posted in Tips, Tool | Tagged , | Leave a comment

将 VMware 最小化到系统托盘

VMware Workstation 最小化默认只能最小化到任务栏, 怎么样才能让它给我们腾出宝贵的任务栏空间, 让它最小化到系统托盘中去呢? Trayconizer 这个小软件能帮我们解决这个问题.

1, 下载 Trayconizer

官网地址: http://www.whitsoftdev.com/trayconizer/
下载地址: http://www.whitsoftdev.com/files/trayconizerw.zip

2, 解压 trayconizerw.zip

解压到任意目录, 压缩包里只有一个 exe 文件
我解压的位置是 D:\Program Files\trayconizerw\Trayconizer.exe

3, 创建 VMware 快捷方式(如果桌面上已经有 VMware 快捷了,可以跳过这一步)

找到 vmware 程序(我的安装位置是 D:\Program Files\VMware\VMware Workstation\vmware.exe ), 右键->发送到->桌面快捷方式

4, 修改 VMware 快捷方式

在桌面快捷方式上右键->属性->"快捷方式"页签->按下面的格式修改"目标"位置内容->应用->确定
"Trayconizer.exe的完整路径" "vmware.exe的完整路径"
注意: 因为 Trayconizer.exe / vmware.exe 路径中可能会有空格(就像"Program Files"这样的目录名), 所以要用双引号包起来.
      两个完整个路径之间要有一个空格符
例如: "D:\Program Files\trayconizerw\Trayconizer.exe" "D:\Program Files\VMware\VMware Workstation\vmware.exe"

5, 运行

双击修改后的快捷方式, 打开 vmware 窗口, 再按最小化..哈..看到效果了吧..它不会再待在任务栏里啦, 而是会自动最小化到系统托盘中去了.

不仅仅是 VMware Workstation , 其它的应用程序都可以用这样的办法来把它们最小化到系统托盘中去哟.

Posted in Tips, Tool | Tagged , | Leave a comment

细说 Javascript 函数

作者:F. Permadi
译者:Sheneyan(子乌)
时间:2006.01.03
英文原文: INTRODUCTION TO JavaScript Functions
子乌注:一篇相当不错的function入门文章,个人感觉相当经典。

词语翻译列表

function:函数(Function未翻译)
declare:定义
assign:指派,分配
functionbody:函数体(就是函数的内容)
object:对象
property:属性
unnamed:匿名(在这里没翻译成未命名)
object oriented programming:面向对象编程
class:类(比如后面的class data type我翻译成类数据类型)
pointer:指针
reassign:重新分配
nest:嵌套
feature:功能,特性
local/global:局部/全局
blueprint:蓝图(?)
user defined:用户自定义
instance:实例
prototype:原型(除了标题都不翻译)
internal:内部
constructor:构造器
duplication:复制

函数:定义
有以下这些方法可以定义一个函数。所有这些都是有效的,但是它们在后台如何实现的则有一些差别。

1, 常用的写法
一般大家都用这个写法来定义一个函数:
functionName([parameters]){functionBody};

Example D1:

function add(a, b){
    return a+b;
}
alert(add(1,2));    // 结果 3

当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我们去调用它)。而且,也许你不知道,当这个函数创建的时候有一个同名的对象也被创建。就我们的例子来说,我们现在有一个对象叫做“add”(要更深入了解,看底下函数:对象节。)

2. 匿名函数
我们也可以通过指派一个变量名给匿名函数的方式来定义它。

Example D2

var add = function(a, b) {
    return a+b;
}
alert(add(1,2));    // 结果 3

这个代码和前一个例子做了同样的事情。也许语法看起来比较奇怪,但它应该更能让你感觉到函数是一个对象,而且我们只是为这个对象指派了一个名称。可以把它看做和var myVar=[1,2,3]一样的语句。以这种方式声明的函数内容也一样会被编译。

当我们指派一个这样的函数的时候,我们并不一定要求必须是匿名函数。在这里,我作了和ExampleD2一样的事情,但我加了函数名“theAdd”,而且我可以通过调用函数名或者是那个变量来引用函数。

Example D2A

var add = function theAdd(a, b){
    return a+b;
}
alert(add(1,2));    // 结果 3
alert(theAdd(1,2)); // 结果也是 3

使用这种方式来定义函数在面向对象编程中是很有用的,因为我们能像底下这样使一个函数成为一个对象的属性。

var myObject = new Object();
myObject.add = function(a, b){return a+b};
// myObject 现在有一个叫做“add”的属性(或方法)
// 而且我可以象下面这样使用它
myObject.add(1, 2);

3, new
我们也可以通过使用运算符new来定义一个函数。
这是一个最少见的定义函数的方式并且并不推荐使用这种方式除非有特殊的理由(可能的理由见下)。语法如下:

varName = new Function([param1Name, param2Name,...paramNName], functionBody);

Example D3:

var add = new Function("a", "b", "return a+b;");
alert(add(3,4));    // 结果 7

我在这里有两个参数叫做a和b,而函数体返回a和b的和。请注意new Function(...)使用了大写F,而不是小写f。 这就告诉javascript,我们将要创建一个类型是Function的对象。 还要注意到,参数名和函数体都是作为字符串而被传递。我们可以随心所欲的增加参数,javascript知道函数体会是右括号前的最后一个字符串(如果没有参数,你可以只写函数体)。你没必要将所有东西都写在一行里(使用\或者使用字符串连接符+来分隔长代码)。\标记告诉JavaScript在下一行查找字符串的其余部分。例子如下:

Read More »

Posted in JavaScritp | Tagged | Leave a comment

常用的 jQuery 插件

自己整理的一些常用的 jQuery 的插件:

http://www.malsup.com/jquery/ [对话框插件/推荐]
http://dev.iceburg.net/jquery/jqModal/ [对话框插件]
http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/ [日历插件]
http://jquery.bassistance.de/validate/demo/ [表单验证]
http://jquery.com/demo/thickbox/ [图片层/对话框]
http://demos.flesler.com/jquery/scrollTo/ [锚点特效]
http://15daysofjquery.com/examples/jqueryEditInPlace/demo.php [div编辑]
http://www.davehauenstein.com/code/jquery-edit-in-place/example/ [div编辑&保存]
http://www.appelsiini.net/projects/jeditable/default.html [div编辑&保存]
http://www.jdempster.com/category/jquery/disableTextSelect/ [禁止鼠标选取]
http://www.phpletter.com/contents/ajaximageeditor/ajax_image_editor.php [图片放大缩小/加图解]
http://www.phpletter.com/Demo/Jquery-Floating-Box-Plugin/ [页面四角浮停DIV]
http://www.visual-blast.com/javascript/jcrop-jquery-image-crop-plugin/ [图片裁切]
http://stanlemon.net/projects/jgrowl.html [类似 163 BLOG右上角提示信息插件]
http://jquery.lukelutman.com/plugins/flash/ [Flash IE7 无虚框插件]

Posted in JavaScritp, html, jquery | Tagged | Leave a comment

怎样保存 Checkbox 值

预备知识点:

二进制数值:
0的二进制数值是   1
1的二进制数值是   1
2的二进制数值是  10
3的二进制数值是  11
4的二进制数值是 100
5的二进制数值是 101
6的二进制数值是 110
...
在 php 中可以通过 decbin() 函数将十进制数字转换为二进制数字.

位运算符 & (按位与), 什么是 & 运算呢?
以 $c = $a & $b 表达式为例, & 运算是将 $a, $b 的二进制数值相比较, 只要两个二进制数中某位都是1, 则结果的二进制数中该位都为1, 否则结果为 0.

假设:
$a 的值为 2 (十进制), 它的二进制数值为  10
$b 的值为 4 (十进制), 它的二进制数值为 100
那么 $c 为 0 (十进制) 因数 $a & $b 的结果为 000(二进制数值), 转换为十进制数值就为 0

假设:
$a 的值为 2 (十进制), 它的二进制数值为  10
$b 的值为 6 (十进制), 它的二进制数值为 110
那么 $c 为 2 (十进制) 因数 $a & $b 的结果为 010(二进制数值), 转换为十进制数值就为 2

Javascript/php/mysql 都支持 & 运算.

OK. 进入正题:
我们现在要记录用户的兴趣爱好, 兴趣爱好有很多选项, 可以复选, 表现在页面上就是一堆的 checkbox , 它看起来像是这样子的

<input type="checkbox" name="hobby[]" value="aa">爱好1 <br>
<input type="checkbox" name="hobby[]" value="bb">爱好2 <br>
<input type="checkbox" name="hobby[]" value="cc">爱好3 <br>
<input type="checkbox" name="hobby[]" value="dd">爱好4 <br>
<input type="checkbox" name="hobby[]" value="ee">爱好5 <br>
<input type="checkbox" name="hobby[]" value="ff">爱好6 <br>
<input type="checkbox" name="hobby[]" value="gg">爱好7 <br>

假设用户勾选的是 "爱好1", "爱好3", "爱好5", 我们要怎么把用户勾选的值保存到数据库呢?

方法1:

用特定的分隔符(比如,)把用户勾选的 value 值串连起来? 那么保存到数据库中的值应该是 "aa,cc,ee"
还有别的方法吗?

方法2:

保存到数据库的值是 "1010100" , 这个字串是怎么得来的呢? 设计这种方法的思想是这样的: 数据库中保存一个长度与复选框个数一样的字符串, 这个字串中的第一位就表示第一个复选框, 如果第一个复选框的勾选了, 那字串的第一位就是1. 同样的道理所以字串的第3位,第5位值为1, 其它位值为0.
还有别的方法吗?

我用的是方法3:

重新设计 checkbox 的值, 将它们设置成2的N(N>=0)次方. 它看起来像这样子:
<input type="checkbox" name="hobby[]" value="1" >爱好1 <br>
<input type="checkbox" name="hobby[]" value="2" >爱好2 <br>
<input type="checkbox" name="hobby[]" value="4" >爱好3 <br>
<input type="checkbox" name="hobby[]" value="8" >爱好4 <br>
<input type="checkbox" name="hobby[]" value="16">爱好5 <br>
<input type="checkbox" name="hobby[]" value="32">爱好6 <br>
<input type="checkbox" name="hobby[]" value="64">爱好7 <br>
而我要保存到数据库中的值是 21, 没错, 它是一个数字, 它是怎么来的呢? 1+4+16 = 21, 它就是将用户勾选的复选框 value 值累加而以.

为什么是2的N(N>=0)次方? ( 1, 2, 4, 8, 16, 32, ... )

<?php
//我们来看看它们的二进制数值有什么特点.
echo decbin(1)."<br>";   //       1
echo decbin(2)."<br>";   //      10
echo decbin(4)."<br>";   //     100
echo decbin(8)."<br>";   //    1000
echo decbin(16)."<br>";  //   10000
echo decbin(32)."<br>";  //  100000
echo decbin(64)."<br>";  // 1000000

//来看问题: 为什么要把 value 值设置为2的N(N>=0)次方?
//因为2的N(N>=0)次方数字的二进制表示一定是最左边第一位是1, 其它位是0,
//而正是这样的特性, 使得任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况.
//什么意思? 举个例子:
//1+2+4 二进制表示是 1+10+100
//1+2+3 二进制表示是 1+10+11  <-- 这样会使右边第一位,第二位出现进位

//再来看个例子
echo decbin(1+2)."<br>";     //    11
echo decbin(1+2+4)."<br>";   //   111
echo decbin(4+8)."<br>";     //  1100
echo decbin(1+4+16)."<br>";  // 10101
//结合"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 很容易分析出上面例子中的规律:
//结果值的二进制数值中如果右边第一位是1, 那么结果值的十进制数值一定是 1+***
//结果值的二进制数值中如果右边第二位是1, 那么结果值的十进制数值一定是 2+***
//结果值的二进制数值中如果右边第一位是1,右边第二位也是1, 那么结果值的十进制数值一定是 1+2+***

//我们回到用户勾选爱好复选框保存到数据库中的值 21 (十进制)
//通俗点, 我们可以这样理解:
//2的N(N>=0)次方数字的和(例如21) 的二进制表示(10101), 从右至左如果第n位为1, 那它十进制一定是 2 的 n-1 次方与其它2的N(N>=0)次方数字的和
//所以 21(二进制表示为 10101) 应该是 (2的(1-1)次方)+(2的(3-1)次方)+(2的(5-1)次方) = 1+4+16

//同样根据"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 结合我们已知的 & 运算, 我们能很方便的判断 任意2的N(N>=0)次方数字相加的和中是否存在一个确定的2的N(N>=0)次方数字
echo (21 & 1)."<br>";   // 1
echo (21 & 2)."<br>";   // 0
echo (21 & 4)."<br>";   // 4
echo (21 & 8)."<br>";   // 0
echo (21 & 16)."<br>";  // 16
echo (21 & 32)."<br>";  // 0
echo (21 & 64)."<br>";  // 0
?>

我们来看看页面前端 javascript 是怎么保存和还原用户勾选的选项的:
在线实例

<input type="button" value="要保存到数据库中的值" onclick="get_save_value('hobby[]')">
<input type="button" value="清除勾选" onclick="clear_all('hobby[]')"> <br>
<br>还原勾选框<br>
<input type="text" name="set_check_value" id="set_check_value"><br>
<input type="button" value='先点击 "清除勾选" 再点我' onclick="set_check('hobby[]', document.getElementById('set_check_value').value)"> <br>

<script language="JavaScript">
/* 重点 */
//还原用户的选取项
function set_check(name, value){
    var obj = document.getElementsByName(name);
    for(var i=0; i<obj.length; i++){
        if( (obj[i].value & value) == obj[i].value ){
            obj[i].checked = true;
        }
    }
}

/* 这不是重点 */
function get_save_value(name){
    var obj = document.getElementsByName(name);
    var saveValue = 0;
    for (var i=0; i<obj.length; i++){
        if (obj[i].checked){
            saveValue += parseInt(obj[i].value);
        }
    }
	document.getElementById("set_check_value").value = saveValue;
    alert(saveValue); //这个就是要存到数据表里的值
}

function clear_all(name){
    var obj = document.getElementsByName(name);
    for (var i=0; i<obj.length; i++){
        obj[i].checked = false;
    }
}
</script>

我们来看看后端数据库是查询用户勾选项的:
假设我们 tableName 中的 hobby 字段是保存用户的兴趣爱好值
一个用户一第记录, 如果前面的例子成功记录到数据库中, 那么 tableName 中应该有一条 hobby==21 的值的记录.

--要查询选择了"爱好1"或者"爱好3"的用户:
--爱好1(value=1)
--爱好3(value=4)
SQL: SELECT * FROM tableName WHERE (hobby&1) OR (hobby&4);

--要查询选择了"爱好1"并且"爱好3"的用户:
--爱好1(value=1)
--爱好3(value=4)
SQL: SELECT * FROM tableName WHERE (hobby&1) AND (hobby&4);

--要查询只选择了"爱好1"和"爱好3"的用户:
--爱好1(value=1)
--爱好3(value=4)
SQL: SELECT * FROM tableName WHERE hobby=(1+4)
Posted in JavaScritp, Mysql, PHP, html | Tagged , , , | Leave a comment

让 Apache 支持 mod_python

mod_pytho 中文文档
http://man.chinaunix.net/develop/python/mod_python/mod_python.html

1, 下载 ModPython-3.3.1 (http://www.apache.org/dist/httpd/modpython/win/3.3.1/), 安装, 安装过程中会讯问 apache 安装目录.
2, 在apache的httpd.conf中加入下面一行:

LoadModule python_module modules/mod_python.so

3, 再加入下面一段

Alias /py/ "d:/PythonCode/"
<Directory "d:/PythonCode/">
    AddHandler mod_python .py
    #PythonHandler mptest
    PythonHandler mod_python.publisher
    PythonDebug On
</Directory>

4, 在 d:/PythonCode/ 目录下新建一名为 mptest.py 的测试文件,内容如下

from mod_python import apache
def handler(req):
   req.content_type = "text/plain"
   req.write("Hello World!")
   return apache.OK

5, 通过 http://127.0.0.1/py/mptest.py 访问测试

可能会遇到的问题:


http://hi.baidu.com/javaway/blog/item/ea7401822bc491aa0cf4d2d8.html

环境:Python:2.5.4 / Apache:2.2
我安装完mod_python之后,在apache的配置文件里httpd.conf,添加了一行:
LoadModule python_module modules/mod_python.so
使得Apache加载mod_python模块
可是在我重新启动Apache时,apache却报错无法启动,看看日志:
[Fri Mar 27 15:07:49 2009] [notice] Parent: Received restart signal -- Restarting the server.
[Fri Mar 27 15:07:49 2009] [notice] Child 948: Exit event signaled. Child process is ending.
httpd.exe: Syntax error on line 127 of D:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf: Cannot load D:/Program Files/Apache Software Foundation/Apache2.2/modules/mod_python.so into server: \xd5\xd2\xb2\xbb\xb5\xbd\xd6\xb8\xb6\xa8\xb5\xc4\xc4\xa3\xbf\xe9\xa1\xa3
[Fri Mar 27 15:07:50 2009] [warn] (OS 995)由于线程退出或应用程序请求,已放弃 I/O 操作。 : winnt_accept: Asynchronous AcceptEx failed.

我又花了很长的时间来查找原因,初始时以为是字符编码问题,然后我又看看mod_python的权限,貌似没有问题。没辙,股沟了一下,在modpython的论坛中有人提出可能是因为Python安装时选择值安装到自己的账户导致的:

Please don't follow up to a different thread with a new question.
Subject now changed.

If you are running Apache as a service, it may be running as a
specific user, not the one which you installed the mod_python code as.
If this is the case, you need to make sure that the user that Apache
is running as has correct access rights to be able to read the module
file.

If this has occurred, you may also have problems with loaded module
then being able to read the installed Python code files.

Generally it is recommended that Apache, Python and mod_python all be
installed as an administrator and not as an individual user.

我不是很确定,但我记得安装Python时的确是选择了单用户,尝试重新安装Python,选择为所有用户安装,重启Apache,OK.
Posted in Apache, Python | Tagged , | Leave a comment

设置 Apache & hosts 本地开发环境

设置本地 Apache 虚拟主机 & 本地 hosts 打造和外网虚拟空间一模一样本地开发环境.

Apache 是全球而署最多的 web server
想全面了解它可以访问官方主页 http://www.apache.org/

Hosts文件是一个用于存储计算机网络中节点信息的文件,它可以将主机名映射到相应的IP地址,实现DNS的功能,它可以由计算机的用户进行控制。
Windows 中它的存放位置是: c:\windows\system32\drivers\etc\hosts
Linux 中它的存放位置是: /etc/hosts

如果你有自己的网站, 但没有自己的本地开发环境, 你想新增一个新功能, 你的操作步骤可能是这样子的:

1, 在本地(本机)把新功能开发好
2, 然后用ftp上传到自己的外网虚拟主机网站目录下
3, 在外网虚拟机空间上测试功能是否正常
4, 如果正常,OK.完成 / 但如果有错, 执行以下步骤:
5, 再修改
6, 再上传
7, 再调试
8, ... <-- 不断循环(4/5/6/7)步骤, 直到功能能正常使用.

显然这样子是费神又费力的, 而且更大的弊端是访问你的网站的用户会有可能看到你调试时的错误信息(如果你的网站有注册用户, 在你调试时十分不凑巧的被他们访问到了你的新功能而引起数据库上错误, 那麻烦就大了)

显然打造本地开发环境是十分有必要的.

前期准备工作:
在本地安装好 Apache+php+mysql , 集成安装包是个不错的选择, 推荐两款集成包:
easyphp(windows) http://www.easyphp.org/
xampp(windows/linux) http://www.apachefriends.org/

假设我们有两个网站 http://dev.kuco , http://wp.kuco 要想打造和我们外网虚拟主机上一模一样的环境
1, 我们要用到的配置 apache 虚拟主机

#将下面内容添加到 Apache 配置文件 httpd.conf 最底端:
#主机ip:端口
NameVirtualHost *:80            

#第一个虚拟主机
<VirtualHost *:80>
ServerAdmin webmaster@dev.kuco
DocumentRoot D:\home\dev.kuco     #指定虚拟主机网站根目录
ServerName dev.kuco               #虚拟主机域名
  <Directory "D:\home\dev.kuco">
  AllowOverride All               #允许rewrite
  </Directory>
</VirtualHost>

#第二个虚拟主机
<VirtualHost *:80>
ServerAdmin kuco@wp.kuco
DocumentRoot D:\home\wp.kuco
ServerName wp.kuco
  <Directory "D:\home\wp.kuco">
  AllowOverride All
  </Directory>
</VirtualHost>

2, 设置本地 hosts

# 如果要访问外网虚拟主机, 在相应的记录行首加上 # 注释掉就可以了
127.0.0.1  dev.kuco   # http://dev.kuco 本地测试环境
127.0.0.1  wp.kuco    # http://wp.kuco  本地测试

3, 将外网虚拟主机网站目录上的程序下载到本地虚拟主机的相应目录
4, 在本地数据库建立好相应的数据库

OK, 我们配置好啦, 现在访问 http://dev.kuco, http://wp.kuco 都会直接访问我们本机上的文件啦.
我们再来看看要新增一个新功能, 我们的操作步骤吧:

1, 在本地(本机)把新功能开发好
2, 直接在本地上测试功能是否正常
3, 如果正常,OK.跳到第*步 / 如果有错, 执行以下步骤:
4, 再修改
5, 再调试
6, ... <-- 不断循环(3/4/5/6)步骤.
*, 将 hosts 中本地测试环境注释掉, 然后再用ftp将程序上传到自己的虚拟主机网站目录下, 完成!
Posted in Apache | Tagged , | Leave a comment

用 jsScrolling 美化你的滚动条

系统自带的滚动条样式设置好像是块硬骨头, 我们只能设定它的边框颜色/背景颜色/3D边框等一些最最最基本的样式, 这对于想要做出一流页面的我们来说简直太简陋了! 做漂亮的页面梦想要破灭了么? NO! jsScrolling 能帮我们来啃掉这块硬骨头~

jsScrolling 能利用 javascript 和 css 来模拟系统滚动条, 达到我们自定义滚动条的目的.
(美中不足的是 jsScrolling 只能模拟垂直滚动条, 暂不支持水平滚动条, 但实际上水平滚动条出现的几率是很小的)

官网地址: http://www.n-son.com/scripts/jsScrolling/index.html
下载地址: http://www.n-son.com/scripts/jsScrolling/jsScrolling.zip
这里面会有简介文件/DEMO/JS文件(压缩&未压缩过的)

jsScrolling 它包括两个部分 jsScroller.js 和 jsScrollbar.js

jsScroller.js 是用来控制内容滚动的, 一个简单的例子
(你可以在这里看到效果 1.html):

<!--
一个最基本的代码结构包括:
1, 默认的样式
2, JS初始化
3, HTML代码格式

注意:
1, 默认css样式必须要有
2, css 样式名不能修改
3, html 代码结构不能修改
-->

<style type="text/css">
.Scroller-Container-Parent{position:relative; width:100px; height:100px; overflow:hidden;}
.Scroller-Container {position: absolute;}
</style>

<script type="text/javascript" src="js/jsScroller.js"></script>
<script type="text/javascript">
var scroller = null;
window.onload = function () {
    scroller = new jsScroller(document.getElementById("div_content"), 350, 100);
}
</script>

<img src="img/up_arrow.gif" onmouseover="scroller.startScroll(0, 5)" onmouseout="scroller.stopScroll()" />
<img src="img/down_arrow.gif" onmouseover="scroller.startScroll(0, -5)" onmouseout="scroller.stopScroll()" />

<div id="div_content" class="Scroller-Container-Parent">
    <div class="Scroller-Container">
        内容...
    </div>
</div>

上面的例子效果似乎没有感觉到滚动条的气息, 那我们来看看 jsScrollbar.js 吧, 一个常见的应用实例
(你可以在这里看到效果 2.html):

<!--
同样要注意的是默认 css 样式和 html 代码结构不能修改. 实例中会有自定义样式, 可以直接在源码里看得到.
(.Scrollbar-Container / .Scroller-Container-Parent 这两个样式是我自己定义的, 这样能更加方便我们去定义自义样式)
-->
<style type="text/css">
.Scrollbar-Container{position:absolute; height:230px; top:0px;}
.Scrollbar-Container .Scrollbar-Up{position:absolute; cursor:pointer; width:30px; height:30px; background-color:#6600FF;}
.Scrollbar-Container .Scrollbar-Down{position: absolute; cursor:pointer; width:30px; height:30px; background-color:#6600FF; top:200px;}
.Scrollbar-Container .Scrollbar-Track{position:absolute; width:30px; height:170px; top:30px;}
.Scrollbar-Container .Scrollbar-Handle{position:absolute; width:30px; height:30px; background-color:#FF0000;}
.Scroller-Container-Parent{position:relative; width:100px; height:100px; overflow:hidden;}
.Scroller-Container {position: absolute;}
</style>

<script type="text/javascript" src="js/jsScroller.js"></script>
<script type="text/javascript" src="js/jsScrollbar.js"></script>

<script type="text/javascript">
var scroller1 = scrollbar1 = scroller2  = scrollbar2 = null;
window.onload = function () {
    //第一个
    scroller1  = new jsScroller(document.getElementById("div_content_1"), 400, 200);
    scrollbar1 = new jsScrollbar(document.getElementById("div_scrollbar_1"), scroller1, false);

    //第二个
    scroller2  = new jsScroller(document.getElementById("div_content_2"), 400, 200);
    scrollbar2 = new jsScrollbar(document.getElementById("div_scrollbar_2"), scroller2, false);
}
</script>

<!-- 1 -->
<div style="position:relative;">
<div id="div_scrollbar_1" class="Scrollbar-Container">
    <div class="Scrollbar-Up"></div>
    <div class="Scrollbar-Down"></div>
    <div class="Scrollbar-Track"><div class="Scrollbar-Handle"></div></div>
</div>
<div id="div_content_1" class="Scroller-Container-Parent">
    <div class="Scroller-Container">
        内容...
    </div>
</div>
</div>
<!--// 1 -->

<!-- 2 -->
<div style="position:relative; margin-top:20px;">
<div id="div_scrollbar_2" class="Scrollbar-Container">
    <div class="Scrollbar-Up"></div>
    <div class="Scrollbar-Down"></div>
    <div class="Scrollbar-Track"><div class="Scrollbar-Handle"></div></div>
</div>
<div id="div_content_2" class="Scroller-Container-Parent">
    <div class="Scroller-Container">
        内容...
    </div>
</div>
</div>
<!--// 2 -->

OK, 看完这些应该足以满足我们日常工作啦, 如果想了解更多, 去官网溜达溜达吧~
赶快去设计属于你自己的滚动条吧~

Posted in Css, JavaScritp, html | Tagged , , | Leave a comment

linux常用命令

#[ 目录/文件 ]################################
#切换目录
cd /home/kuco/  #切换到 /home/kuco/ 目录
cd ..           #切换到上一级目录
cd ~            #切换到当前用户的家目录
cd              #切换到当前用户的家目录

#显示目录文件
ls              #显示当前目录文件列表
                # 可带参数:
                # -a 列出全部文件,包括隐藏文件(文件名以.开头的文件)
                # -l 详细列表

#创建目录
mkdir dirname

#删除目录
rm -rf dirname  # -r 递归处理
                # -f 强制删除(不显示确定删除提示对话)
rm -ri dirname  # -i 显示确定删除提示框(推荐带上此参数)

#复制
cp -r dirname1 dirname2   # 将 dirname1 复制到 dirname2 中
                          # 执行结果 ./dirname2/dirname1/*
cp -r dirname1/* dirname2 # 推荐这样写

#移动/重命名
mv filename1 filename2     # 将 filename1 重命令为 filename2
mv -r dirname1/* dirname2/ # 将 dirname1 下面的文件称动到 dirname2 中

#查看文本内容
cat filename     # 显示 filename 全部第1行到第N行的内容
tac filename     # 显示 filename 全部第N行到第1行的内容, 逆向显示
more filename    # 一屏一屏的显示内容, 回车翻页
less filename    # 显示内容, 可用k/j上下翻动, q退出
head -3 filename # 只显示 filename 前3行的内容
tail -3 filename # 只显示 filename 最后3行的内容
tail -f filename # 实时监视 filename 最后10行内容(常用于查看日志)
sed -n '5,10p' filename     #显示 filename 第5行到第10行的内容
head -3 filename | tail -1  #查看 filename 第3行内容

#统计文本文件行数
wc filename      # 行数(-l),字数(-w),字节数(-c)

#查找命令位置
whereis php      # 查找 php 程序目录

#按文件名查找
find /root -name test.* # 在 /root 目录下查找文件名为 test.* 的文件

#在文件内部查找
grep -r "aaaa" /root/*  # 在 /root 目录下查找内容包含有 "aaaa" 字串的文件

#[ 系统 ]################################
top    # 显示,管理执行中的程序
free   # 内存使用和swap空间使用情况
ps     # 查看进程
whoami #查看当前登录用户名

#切换用户
su kuco #切换到 kuco 用户
su      #切换到 root 用户

#新建一个 www 组
groupadd www

#删除 www 分组
groupdel www

#在 www 组里新建一个 wwwuser 用户
adduser -g wwwuser www

#删除用户
userdel username

#修改 username 用户的密码
passwd username

#修改 www 用户密码
passwd www

#修改 dirname 目录下所有文件拥有者改为 www 组下的 wwwuser 用户
chown -R wwwuser:www dirname

#修改 dirname 目录下所有文件权限为可读可写可执行
chmod -R 777 dirname

#[ 管道 ]################################
# 管道:把上一个命令执行的结果交给下一个命令
#      命令1|命令2|命令3......|命令n
ls -Rl /etc | more   #分页(more)显示(ls -Rl /etc)结果
cat /etc/passwd | wc #显示文件结果, 再显示(wc)结果
ls -l | grep "abc"   #只显示 ls 结果只含有 "abc" 的文件/目录

#[ 应用 ]################################
#解压 abc.tar.gz 到 /opt 目录下
tar -xvfz abc.tar.gz -C /opt

#压缩 /home/kuco 为 /root/kuco.tar.gz
tar -zcvf /root/kuco.tar.gz /home/kuco

#将程序运行结果保存到文件中
ls > filename  #将 ls 的执行结果保存到 filename 中
ls >> filename #将 ls 的执行结果追加保存到 filename 中
Posted in Linux, Tips, shell | Tagged , | Leave a comment

Mysql 事务简介

什么是事务?
通俗点来说, 事务就是对一组由N条SQL语句(N>=1)组成的逻辑处理单元进行并发控制. 当这组SQL语句都执行成功时才会对数据库构成实际影响. 否则只要有一条SQL语句执行失败, 那么整组SQL都不会执行成功, 都不会对数据库有实际影响. 这样能确保这个事务中的这组SQL操作的统一性, 保证数据一致性.

我们来结合实际的例子来理解事务的概念:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 建立不支持事务的数据表 tbl_a
CREATE TABLE IF NOT EXISTS `tbl_a` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 ;

-- 2, 为 tbl_a 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
INSERT INTO tbl_a (val) VALUES ('a');
INSERT INTO tbl_a (val) VALUES ('b');
INSERT INTO tbl_a (vals) VALUES ('c'); -- 因为表中没有 vals 这个字段, 执行到这句时会报错.
INSERT INTO tbl_a (val) VALUES ('d');  -- 因为程序已经中断, 这句不执行

-- 3, 我们来看看 tbl_a 中的数据, 会发现有两条数据.
SELECT * FROM tbl_a;
--   +----+-----+
--   | id | val |
--   +----+-----+
--   |  1 | a   |
--   |  2 | b   |
--   +----+-----+
--   很好理解: 因为我们四条语句一并提交, mysql 还是会一条一条的执行:
--   执行第一句, 没有ERROR, 对数据库产生实际影响, 将 'a' 真真实实的插入到 tbl_a 中
--   执行第二句, 没有ERROR, 对数据库产生实际影响, 将 'b' 真真实实的插入到 tbl_a 中
--   执行第三句, 因为没有指定的字段, 抛出ERROR, 程序中断执行.

接下来我们再看看事务是怎么处理的:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 建立支持事务的数据表 `tbl_b`
CREATE TABLE IF NOT EXISTS `tbl_b` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 ;

-- 2, 为 tbl_b 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
begin; -- 开启一个事务
INSERT INTO tbl_b (val) VALUES ('a');
INSERT INTO tbl_b (val) VALUES ('b');
INSERT INTO tbl_b (vals) VALUES ('c'); -- 报错
INSERT INTO tbl_b (val) VALUES ('d');
commit;

-- 3, 我们来看看 tbl_b 中的数据, 会和 tbl_a 中的数据有什么差别呢?
SELECT * FROM tbl_b;
--   Empty set (0.00 sec)
--   一条数据也没有, 哈. 这就是事务与非事务的区别,
--   因为在事务中遇到了一个错误, 所整个事务中的 SQL 语句都不会对数据库构成实际影响

OK. 现在对事务有了形像的认识之后我们再来结合其它的例子进一步学习事务:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 清空 tbl_b 记录
TRUNCATE TABLE `tbl_b`

-- 2, 为 tbl_b 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
-- begin; -- 注意没有执行 begin
INSERT INTO tbl_b (val) VALUES ('a');
INSERT INTO tbl_b (val) VALUES ('b');
INSERT INTO tbl_b (vals) VALUES ('c'); -- 报错
INSERT INTO tbl_b (val) VALUES ('d');
-- commit;

-- 3, 我们来看看 tbl_b 中的数据, 会和有执行 begin 的效果有什么差别?
SELECT * FROM tbl_b;
--   +----+-----+
--   | id | val |
--   +----+-----+
--   |  1 | a   |
--   |  2 | b   |
--   +----+-----+
--   有两条数据, 这是为什么?
--   因为事务数据表中的事务默认是自动提交的(AUTOCOMMIT), 它的执行过程是:
--   开启一个事务, 执行第一句, 没有ERROR, 提交事务, 对数据库产生实际影响, 将'a'真真实实的插入到 tbl_b 中
--   开启一个事务, 执行第二句, 没有ERROR, 提交事务, 对数据库产生实际影响, 将'b'真真实实的插入到 tbl_b 中
--   开启一个事务, 执行第三句, 因为没有指定的字段, 抛出ERROR, 程序中断执行.
--   这样明白了为什么要使用 begin 了吧, 换句话说,如果事务表中没有 begin,那它和非事务表执行的效果是一样的

下面是一个成功的例子:

-- 在 phpMyAdmin 中执行下面的操作
-- 1, 清空 tbl_b 记录
TRUNCATE TABLE `tbl_b`;

-- 2, 为 tbl_b 插入数据, 将下面 4 条语句全部复制, 用 phpMyAdmin 一并执行
begin;
INSERT INTO tbl_b (val) VALUES ('a');
INSERT INTO tbl_b (val) VALUES ('b');
INSERT INTO tbl_b (val) VALUES ('c');
INSERT INTO tbl_b (val) VALUES ('d');
-- rollback; -- roolback 可以理解为 un-commit, 不提交
commit; -- 注意最后要有 conmmit; 如果这有这一句会怎样? 动手试试吧.

-- 3, 我们来看看 tbl_b 中的数据, 四条数据成功插入.
SELECT * FROM tbl_b;

总结一下:
1, 在 Mysql 中要让数据表支持事务, 必须使用 InnoDB 或 BDB 数据引擎.
2, 事务数据表默认是 autocommit 的, 要开启一个事务应该使用 begin; 或者使用 SET AUTOCOMMIT={1|0} 来设置是否自动提交
3, 事务一定要 commit , 否则没有任何效果

Posted in Mysql | Tagged , | Leave a comment