去除a、button虚线框

IE5+ :设置 a 标签私有属性 hidefocus 值为 true
Firefox / Chrome / Opera / Safari : 设置 a 标签或 a:focus 的 outline 属性为 none

a:active, a:focus{-moz-outline:none;outline:none;ie-dummy:expression_r(this.hideFocus=true);}

 

PS:ie-dummy:是属性名

发表在 css | 标签为 | 3 条评论

Ubuntu下vim+ctags的配置

Ubuntu下vim+ctags的配置
ctags可以建立源码树的索引,使程序员在编程时能迅速定位函数、变量、宏定义等位置去查看原形
以下是在ubuntu下ctags的下载安装和配置过程:

下载并安装ctags,终端输入命令
sudo apt-get install ctags

建立源码索引,比如我经常需要查阅Linux的内核代码,而这些代码放在/home/hjw951/arm/linux-2.6.12目录下
那么在终端进入到该目录后,输入命令ctags -R *,你会发现多了一个tags文件,这个就是索引文件

向vim注册索引文件tags的路径,用root用户在终端输入gedit /etc/vim/vimrc
在打开文件的最后添加一行(当然,具体路径根据你自己的情况)
set tags=/home/hjw951/arm/linux-2.6.12/tags

然后关闭终端重新打开,你就可以用VIM在任意地方查看有关Linux的函数原形

------------------------------------
最简单的使用方法举例
用vi在任意目录写一个test.c文件,内容如下:

int main(void)
{
        printf("HelloWorld!");
        return 0;
}

 

写好后末行模式输入w保存好(不要退出vi),按Esc回到指令模式,把光标停留在printf上
然后按 Ctrl+],vi会自动跳到Linux系统函数printf()处,这时我们能查看printf()的原形
查看完了,按Ctrl+o 就回到原来的地方

发表在 Linux | 标签为 , | 留下评论

yaf.so doesn’t appear to be a valid Zend extension

把zend_extension换成extention即可

[yaf]
extension = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/yaf.so"

 

发表在 php, yaf | 标签为 | 一条评论

修改nginx配置文件 支持php的pathinfo路径模式

nginx模式默认是不支持pathinfo模式的,类似info.php/hello形式的url会被提示找不到页面。下面的通过正则找出实际文件路径和pathinfo部分的方法,让nginx支持pathinfo。
nginx配置实例:
在nginx.conf的server部分:

user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    server {
        listen       80;
        server_name  localhost;

        charset utf-8;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.php index.html index.htm;
        }

        error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/html$fastcgi_script_name;
            include        fastcgi_params;
	    include        pathinfo_params;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
            deny  all;
        }
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

 

fastcgi_params:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

#fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

 

pathinfo_params:

set $path_info "";
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;

 

nginx_pathinfo配置

发表在 服务器 | 标签为 | 留下评论

windows查看某个端口号被占用并结束此进程

1、netstat -ano |findstr 3306 //查看3306端口是否存在

2、tasklist |findstr 3036(PID号)//查看pid为3036的是什么程序在用

3、taskkill /T /F /PID 3036 //强制(/F参数)杀死pid为3036的所有进程包括子进程(/T参数)

发表在 windows | 留下评论

Coreseek在GCC 4.7上编译不通过的问题

今天在ubuntu在安装coreseek 4.1-beta时碰到的问题,在g++编译sphinxexpr.cpp时:

g++ -DHAVE_CONFIG_H -I. -I../config -DSYSCONFDIR=”\”/opt/coreseek-3.2.14/etc\”" -DDATADIR=”\”/opt/coreseek-3.2.14/var/data\”" -I/usr/local/include -pthread -I/usr/include/mysql -fPIC -pipe -fstack-protector –param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -DBIG_JOINS=1 -fomit-frame-pointer -g -I/opt/mmseg-3.2.14/include/mmseg/ -Wall -g -D_FILE_OFFSET_BITS=64 -O3 -DNDEBUG -MT sphinxexpr.o -MD -MP -MF .deps/sphinxexpr.Tpo -c -o sphinxexpr.o sphinxexpr.cpp sphinxexpr.cpp: In constructor ‘ExprParser_t::ExprParser_t(CSphSchema*, ISphExprHook*)’: sphinxexpr.cpp:742:17: warning: ‘ExprParser_t::m_pExtra’ will be initialized after [-Wreorder] sphinxexpr.cpp:711:19: warning: ‘ISphExprHook* ExprParser_t::m_pHook’ [-Wreorder] sphinxexpr.cpp:698:2: warning: when initialized here [-Wreorder] sphinxexpr.cpp: In instantiation of ‘int Expr_In_c::IntEval(const CSphMatch&) const [with T = float]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1823:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1823:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1823:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_In_c::IntEval(const CSphMatch&) const [with T = long long int]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1823:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1823:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1823:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_In_c::IntEval(const CSphMatch&) const [with T = int]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1823:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1823:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1823:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_Interval_c::IntEval(const CSphMatch&) const [with T = float]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1777:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1777:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1777:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_Interval_c::IntEval(const CSphMatch&) const [with T = long long int]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1777:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1777:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1777:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_Interval_c::IntEval(const CSphMatch&) const [with T = int]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1777:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1777:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1777:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_IntervalConst_c::IntEval(const CSphMatch&) const [with T = float]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1746:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1746:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1746:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_IntervalConst_c::IntEval(const CSphMatch&) const [with T = long long int]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1746:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1746:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1746:43: note: use ‘this->ExprEval’ instead sphinxexpr.cpp: In instantiation of ‘int Expr_IntervalConst_c::IntEval(const CSphMatch&) const [with T = int]’: sphinxexpr.cpp:3152:1: required from here sphinxexpr.cpp:1746:43: error: ‘ExprEval’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] sphinxexpr.cpp:1746:43: note: declarations in dependent base ‘Expr_ArgVsSet_c’ are not found by unqualified lookup sphinxexpr.cpp:1746:43: note: use ‘this->ExprEval’ instead make[2]: *** [sphinxexpr.o] Error 1 make[2]: Leaving directory `/home/mac/Downloads/coreseek-4.1-beta/csft-4.1/src’ make[1]: *** [all] Error 2 make[1]: Leaving directory `/home/mac/Downloads/coreseek-4.1-beta/csft-4.1/src’ make: *** [all-recursive] Error 1

在替换为gcc 4.8.0后仍然发生了类似问题,但是在自己的Mac OS X 10.6.8上类似的编译却没有碰到这个问题,于是觉得很奇怪。

搜索之后,仅找到一个有用的链接:http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=667378,是关于coreseek上游的sphinx的同样问题的,看了一下了解似乎是gcc 4.7、gcc 4.8的C++作用域的问题(?),上面的debian bugs里面提供了一个patch,看了下patch的内容,也对自己本地的coreseek的制作了同样的补丁,压缩包发布如下,使用时注意版本:

解压后,用sphinxexpr.cpp覆盖coreseek-4.1-beta/csft-4.1/src下的同名文件重新编译即可

原作者制作的补丁文件下载:http://rrurl.cn/pjpA4B

发表在 Sphinx | 留下评论

Linux下patch的制作和应用

首先介绍一下diff和patch。在这里不会把man在线文档上所有的选项都介绍一下,那样也没有必要。在99%的时间里,我们只会用到几个选项。所以必须学会这几个选项。
1、diff
--------------------
NAME
diff – find differences between two files
SYNOPSIS
diff [options] from-file to-file
--------------------

简 单的说,diff的功能就是用来比较两个文件的不同,然后记录下来,也就是所谓的diff补丁。语法格式:diff 【选项】 源文件(夹) 目的文件(夹),就是要给源文件(夹)打个补丁,使之变成目的文件(夹),术语也就是“升级”。下面介绍三个最为常用选项:

-r 是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。
-N 选项确保补丁文件将正确地处理已经创建或删除文件的情况。
-u 选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。

2、patch
------------------
NAME
patch – apply a diff file to an original
SYNOPSIS
patch [options] [originalfile [patchfile]]
but usually just
patch -pnum ------------------
简单的说,patch就是利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。这样说就意味着你可以有源文件(夹)――>目的文件(夹),也可以目的文件(夹)――>源文件(夹)。下面介绍几个最常用选项:
-p0 选项要从当前目录查找目的文件(夹)
-p1 选项要忽略掉第一层目录,从当前目录开始查找。
************************************************************
在这里以实例说明:
— old/modules/pcitable Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable Tue Dec 19 20:05:41 2000
如果使用参数-p0,那就表示从当前目录找一个叫做old的文件夹,在它下面寻找modules下的pcitable文件来执行patch操作。
如果使用参数-p1, 那就表示忽略第一层目录(即不管old),从当前目录寻找modules的文件夹,在它下面找pcitable。这样的前提是当前目 录必须为modules所在的目录。而diff补丁文件则可以在任意位置,只要指明了diff补丁文件的路径就可以了。当然,可以用相对路径,也可以用绝 对路径。不过我一般习惯用相对路径。
************************************************************

-E 选项说明如果发现了空文件,那么就删除它
-R 选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)
下面结合具体实例来分析和解决,分为两种类型:为单个文件打补丁和为文件夹内的多个文件打补丁。
环境:在RedHat 9.0下面以armlinux用户登陆。
目录树如下:
|– bootloader
|– debug
|– images
|– kernel
|– program
|– rootfiles
|– software
|– source
|– sysapps
|– tmp
|– tools
下面在program文件夹下面建立patch文件夹作为实验用,然后进入patch文件夹。
一、为单个文件进行补丁操作
1、建立测试文件test0、test1
[armlinux@lqm patch]$ cat >>test0< > 111111
> 111111
> 111111
> EOF
[armlinux@lqm patch]$ more test0
111111
111111
111111
[armlinux@lqm patch]$ cat >>test1< > 222222
> 111111
> 222222
> 111111
> EOF
[armlinux@lqm patch]$ more test1
222222
111111
222222
111111
2、使用diff创建补丁test1.patch
[armlinux@lqm patch]$ diff -uN test0 test1 > test1.patch
【注:因为单个文件,所以不需要-r选项。选项顺序没有关系,即可以是-uN,也可以是-Nu。】
[armlinux@lqm patch]$ ls
test0 test1 test1.patch
[armlinux@lqm patch]$ more test1.patch
************************************************************
patch文件的结构
补丁头
补丁头是分别由—/+++开头的两行,用来表示要打补丁的文件。—开头表示旧文件,+++开头表示新文件。
一个补丁文件中的多个补丁
一个补丁文件中可能包含以—/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。

块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。
块的缩进
块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。
块的第一列
+号表示这一行是要加上的。
-号表示这一行是要删除的。
没有加号也没有减号表示这里只是引用的而不需要修改。
************************************************************
***diff命令会在补丁文件中记录这两个文件的首次创建时间,如下***
— test0 2006-08-18 09:12:01.000000000 +0800
+++ test1 2006-08-18 09:13:09.000000000 +0800
@@ -1,3 +1,4 @@
+222222
111111
-111111
+222222
111111
[armlinux@lqm patch]$ patch -p0 < test1.patch
patching file test0
[armlinux@lqm patch]$ ls
test0 test1 test1.patch
[armlinux@lqm patch]$ cat test0
222222
111111
222222
111111
3、可以去除补丁,恢复旧版本
[armlinux@lqm patch]$ patch -RE -p0 < test1.patch
patching file test0
[armlinux@lqm patch]$ ls
test0 test1 test1.patch
[armlinux@lqm patch]$ cat test0
111111
111111
111111
二、为多个文件进行补丁操作
1、创建测试文件夹
[armlinux@lqm patch]$ mkdir prj0
[armlinux@lqm patch]$ cp test0 prj0
[armlinux@lqm patch]$ ls
prj0 test0 test1 test1.patch
[armlinux@lqm patch]$ cd prj0/
[armlinux@lqm prj0]$ ls
test0
[armlinux@lqm prj0]$ cat >>prj0name< > ——–
> prj0/prj0name
> ——–
> EOF
[armlinux@lqm prj0]$ ls
prj0name test0
[armlinux@lqm prj0]$ cat prj0name
——–
prj0/prj0name
——–
[armlinux@lqm prj0]$ cd ..
[armlinux@lqm patch]$ mkdir prj1
[armlinux@lqm patch]$ cp test1 prj1
[armlinux@lqm patch]$ cd prj1
[armlinux@lqm prj1]$ cat >>prj1name< > ———
> prj1/prj1name
> ———
> EOF
[armlinux@lqm prj1]$ cat prj1name
———
prj1/prj1name
———
[armlinux@lqm prj1]$ cd ..

2、创建补丁
[armlinux@lqm patch]$ diff -uNr prj0 prj1 > prj1.patch
[armlinux@lqm patch]$ more prj1.patch
diff -uNr prj0/prj0name prj1/prj0name
— prj0/prj0name 2006-08-18 09:25:11.000000000 +0800
+++ prj1/prj0name 1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
———
-prj0/prj0name
———
diff -uNr prj0/prj1name prj1/prj1name
— prj0/prj1name 1970-01-01 08:00:00.000000000 +0800
+++ prj1/prj1name 2006-08-18 09:26:36.000000000 +0800
@@ -0,0 +1,3 @@
+———
+prj1/prj1name
+———
diff -uNr prj0/test0 prj1/test0
— prj0/test0 2006-08-18 09:23:53.000000000 +0800
+++ prj1/test0 1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
-111111
-111111
-111111
diff -uNr prj0/test1 prj1/test1
— prj0/test1 1970-01-01 08:00:00.000000000 +0800
+++ prj1/test1 2006-08-18 09:26:00.000000000 +0800
@@ -0,0 +1,4 @@
+222222
+111111
+222222
+111111
[armlinux@lqm patch]$ ls
prj0 prj1 prj1.patch test0 test1 test1.patch
[armlinux@lqm patch]$ cp prj1.patch ./prj0
[armlinux@lqm patch]$ cd prj0
[armlinux@lqm prj0]$ patch -p1 < prj1.patch
patching file prj0name
patching file prj1name
patching file test0
patching file test1
[armlinux@lqm prj0]$ ls
prj1name prj1.patch test1
[armlinux@lqm prj0]$ patch -R -p1 < prj1.patch
patching file prj0name
patching file prj1name
patching file test0
patching file test1
[armlinux@lqm prj0]$ ls
prj0name prj1.patch test0
-------------------------------------------------
总结一下:
单个文件
diff –uN from-file to-file >to-file.patch
patch –p0 < to-file.patch
patch –RE –p0 < to-file.patch

多个文件
diff –uNr from-docu to-docu >to-docu.patch
patch –p1 < to-docu.patch
patch –R –p1

发表在 Linux | 留下评论

linux 如何结束进程

首先使用ps -ef命令确定要杀死进程的PID,然后输入以下命令:
# kill -pid
注释:标准的kill命令通常都能达到目的。终止有问题的进程,并把进程的资源释放给系统。然而,如果进程启动了子进程,只杀死父进程,子进程仍在运行,因此仍消耗资源。为了防止这些所谓的“僵尸进程”,应确保在杀死父进程之前,先杀死其所有的子进程。
*确定要杀死进程的PID或PPID
# ps -ef | grep httpd
结束进程
# kill -l PID
-l选项告诉kill命令用好像启动进程的用户已注销的方式结束进程。当使用该选项时,kill命令也试图杀死所留下的子进程。但这个命令也不是总能成功–或许仍然需要先手工杀死子进程,然后再杀死父进程。
给父进程发送一个TERM信号,试图杀死它和它的子进程。
# kill -TERM PPID
*killall命令
killall命令杀死同一进程组内的所有进程。其允许指定要终止的进程的名称,而非PID。
# killall httpd
*停止和重启进程
有时候只想简单的停止和重启进程。如下:
# kill -HUP PID
该命令让Linux和缓的执行进程关闭,然后立即重启。在配置应用程序的时候,这个命令很方便,在对配置文件修改后需要重启进程时就可以执行此命令。

发表在 Linux | 留下评论

jQuery插件开发指南

入门

编写一个jQuery插件开始于给jQuery.fn加入​​新的功能属性,此处添加的对象属性的名称就是你插件的名称:

jQuery.fn.myPlugin = function(){

//你自己的插件代码

};
用户非常喜欢的$符号哪里去了? 它仍然存在,但是,为了避免和其他JavaScript库冲突,我们最好将jQuery传递给一个自我执行的封闭程序,jQuery在此程序中映射为$符号,这样可以避免$号被其他库覆写。

(function($){
$.fn.m​​yPlugin = function(){

//你自己的插件代码

};
})(jQuery);
在这个封闭程序中,我们可以无限制的使用$符号来表示jQuery函数。

环境

现在,我们可以开始编写实际的插件代码。 但是,在这之前,我们必须得对插件所处的环境有个概念。 在插件的范围里, this关键字代表了这个插件将要执行的jQuery对象, 这里容易产生一个普遍的误区,因为在其他包含callback的jQuery函数中,this关键字代表了原生的DOM元素。这常常会导致开发者误将this关键字无谓的包在jQuery中,如下所示。

(function($){

$.fn.m​​yPlugin = function(){

//此处没有必要将this包在$号中如$(this),因为this已经是一个jQuery对象。
//$(this)等同于 $($(‘#element’));

this.fadeIn(’normal’,funciton(){

//此处callback函数中this关键字代表一个DOM元素

});

};
})(jQuery);
$(’#element’)myPlugin();

基础知识

现在,我们理解了jQuery插件的基础知识,让我们写一个插件,做一些事情。

(function($){

$.fn.m​​axHeight = function(){

var max = 0;

this.each(function(){
max = Math.max(max, $(this).height());
});

return max;
};
})(jQuery);
var tallest = $(’div’).maxHeight(); //返回高度最大的div元素的高度
这是一个简单的插件,利用.height()返回页面中高度最大的div元素的高度。

维护Chainability

很多时候,一个插件的意图仅仅是以某种方式修改收集的元素,并把它们传递给链中的下一个方法。 这是jQuery的设计之美,是jQuery如此受欢迎的原因之一。 因此,要保持一个插件的chainability,你必须确保你的插件返回this关键字。

(function($){

$.fn.lockDimensions = function(type),

return this.each(function(){

var $this = $(this);

if( !type || type == ‘width’){
$this.width($this.width());
}

if(!type || type == ‘height’){
$this.height($this.height());
}

});

};
})(jQuery);
$(’div’).lockDimensions(’width’).CSS(’color’,'red’)。
由于插件返回this关键字,它保持了chainability,这样jQuery收集的元素可以继续被jQuery方法如.css控制。 因此,如果你的插件不返回固有的价值,你应该总是在其作用范围内返回this关键字。 此外,你可能会推断出,传递给插件的参数将会在插件的作用范围内被传递。 因此,在前面的例子,字符串’width’变成了插件的类型参数。

默认值和选项

对于比较复杂的和提供了许多选项可定制的的插件,最好有一个当插件被调用的时候可以被拓展的默认设置(通过使用$.extend)。 因此,相对于调用一个有大量参数的插件,你可以调用一个对象参数,包含你了你想覆写的设置。

(function($){

$.fn.tooltip = function(options){

//创建一些默认值,拓展任何被提供的选项
var settings = $.extend({
‘location’:’top’,
‘background-color’:’blue’
},options);

return this.each(function(){

// Tooltip插件代码

});

};
})(jQuery);
$(’div’).tooltip({
‘location’:’left’
});
在这个例子中,调用tooltip插件时覆写了默认设置中的location选项,background-color选项保持默认值,所以最终被调用的设定值为:

{
‘location’:’left’,
‘background-color’:’blue’
}
这是一个很灵活的方式,提供一个高度可配置的插件,而无需开发人员定义所有可用的选项。

命名空间

正确命名空间你的插件是插件开发的一个非常重要的一部分。 正确的命名空间,可以保证你的插件将有一个非常低的机会被其他插件或同一页上的其他代码覆盖。 命名空间也使得你的生活作为一个插件开发人员更容易,因为它可以帮助你更好地跟踪你的方法,事件和数据。

插件方法

在任何情况下,一个单独的插件不应该在jQuery.fnjQuery.fn对象里有多个命名空间。

(function($){

$.fn.tooltip = function(options){
// this
};
$.fn.tooltipShow = function(){
// is
};
$.fn.tooltipHide = function(){
// bad
};
$.fn.tooltipUpdate = function(content),
// !!!
};

})(jQuery);
这是不被鼓励的,因为它$.fn使$.fn命名空间混乱。 为了解决这个问题,你应该收集对象文本中的所有插件的方法,通过传递该方法的字符串名称给插件以调用它们。

(function($){

var methods = {
init :function(options){
// this
},
show :function(){
// is
},
hide :function(){
// good
},
update :function(content){
// !!!
}
};

$.fn.tooltip = function(method),

// 方法调用
if(methods[method]){
return methods[method].apply(this, Array.prototype.slice.call(arguments,1));
} else if(typeof method === ‘object’ || ! method){
return methods.init.apply(this, arguments);
}else{
$.error(’Method’+ method + ‘does not exist on jQuery.tooltip’);
}

};

})(jQuery的);

//调用init方法
$(’div’).tooltip()。

/ /调用init方法
$(’div’).tooltip({
foo:’bar’
});
// 调用hide方法
$(’div’).tooltip(’hide’);
//调用Update方法
$(’div’).tooltip(’update’,’This is the new tooltip content!’);
这种类型的插件架构允许您封装所有的方法在父包中,通过传递该方法的字符串名称和额外的此方法需要的参数来调用它们。 这种方法的封装和架构类型是jQuery插件社区的标准,它被无数的插件在使用,包括jQueryUI中的插件和widgets。

事件

一个鲜为人知bind方法的功能即允许绑定事件命名空间。 如果你的插件绑定一个事件,一个很好的做法是赋予此事件命名空间。 通过这种方式,当你在解除绑定的时候不会干扰其他可能已经绑定的同一类型事件。 你可以通过追加命名空间到你需要绑定的的事件通过 ‘.‘。

(function($){

var methods = {
init :function(options){

return this.each(function(){
$(window).bind(’resize.tooltip’,methods.reposition);
});

},
destroy :function(){

return this.each(function(){
$(window).unbind(’.tooltip’);
})

},
reposition :function(){
//…
},
show :function(){
//…
},
hide :function(){
//…
},
update :function(content){
//…
}
};

$.fn.tooltip = function(method),

if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === ‘object’ || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( ‘Method ‘ + method + ‘ does not exist on jQuery.tooltip’ );
}
};

})(jQuery);
$(’#fun“).tooltip()。
//一段时间之后… …
$(’#乐趣“).tooltip(’destroy’)。
在这个例子中,当tooltip通过init方法初始化时,它将reposition方法绑定到resize事件并给reposition非那方法赋予命名空间通过追加.tooltip。 稍后, 当开发人员需要销毁tooltip的时候,我们可以同时解除其中reposition方法和resize事件的绑定,通过传递reposition的命名空间给插件。 这使我们能够安全地解除事件的绑定并不会影响到此插件之外的绑定。

数据

通常在插件开发的时候,你可能需要记录或者检查你的插件是否已经被初始化给了一个元素。 使用jQuery的data方法是一个很好的基于元素的记录变量的途径。尽管如此,相对于记录大量的不同名字的分离的data, 使用一个单独的对象保存所有变量,并通过一个单独的命名空间读取这个对象不失为一个更好的方法。

(function( $ ){

var methods = {
init : function( options ) {

return this.each(function(){

var $this = $(this),
data = $this.data(‘tooltip’),
tooltip = $(‘

‘, {
text : $this.attr(‘title’)
});

// If the plugin hasn’t been initialized yet
if ( ! data ) {

/*
Do more setup stuff here
*/

$(this).data(‘tooltip’, {
target : $this,
tooltip : tooltip
});

}
});
},
destroy : function( ) {

return this.each(function(){

var $this = $(this),
data = $this.data(‘tooltip’);

// Namespacing FTW
$(window).unbind(‘.tooltip’);
data.tooltip.remove();
$this.removeData(‘tooltip’);

})

},
reposition : function( ) { // … },
show : function( ) { // … },
hide : function( ) { // … },
update : function( content ) { // …}
};

$.fn.tooltip = function( method ) {

if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === ‘object’ || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( ‘Method ‘ + method + ‘ does not exist on jQuery.tooltip’ );
}

};

})( jQuery );
将数据通过命名空间封装在一个对象中,可以更容易的从一个集中的位置读取所有插件的属性。

总结和最佳做法

编写jQuery插件允许你做出库,将最有用的功能集成到可重用的代码,可以节省开发者的时间,使开发更高效。 开发jQuery插件时,要牢记:

始终包裹在一个封闭的插件: (function( $ ){ /* plugin goes here */ })( jQuery );(function($) {})(jQuery);
不要冗余包裹this关键字在插件的功能范围内
除非插件返回特定值,否则总是返回this关键字来维持chainability 。
传递一个可拓展的默认对象参数而不是大量的参数给插件。
不要在一个插件中多次命名不同方法。
始终命名空间的方法,事件和数据。

发表在 jQuery | 标签为 | 留下评论

增加Linux系统的swap分区的大小

说明:我的电脑的物理内存大小为8G,安装RHEL5.0 Linux时swap分区设置的大小为2G;现在计划在其上安装Oracle 10g,Oracle安装时要求swap分区大小为8G,所以需要增加swap分区大小。

1、查看当前的分区情况:

#free -m

2、创建swap分区目录

#mkdir -p /home/swap

3、增加交换分区文件及大小,其中的 count 等于想要的块大小。

#dd if=/dev/zero of=/home/swap/swapfile bs=1024 count=8192000

4、设置交换文件

#mkswap /home/swap/swapfile

5、启用交换分区文件

#swapon /home/swap/swapfile

6、如果要在引导时自动启用,则编辑/etc/fstab文件,添加如下行:

/home/swap/swapfile swap swap defaults 0 0

发表在 Linux | 留下评论