tbwshc

#

Oracle Buys Finnish Open-Source Developer

Oracle scooped up another small technology company on Friday, announcing its acquisition of Finnish open-source database technology developer Innobase. Financial terms of the deal were not disclosed.

Innobase, based in Helsinki, is the creator of InnoDB, an add-on storage engine for MySQL. InnoDB is distributed under the GNU GPL (General Public License) open-source license. The software is bundled with MySQL through a contractual agreementb that comes up for renewal next year; Oracle said it expects to negotiate an extension of that contract.


"Oracle intends to continue developing the InnoDB technology and expand our commitment to open source software," Charles Rozwat, Oracle's executive vice president in charge of database and middleware technology, said in a prepared statement. "Oracle has already developed and contributed an open source clustered file system to Linux. We expect to make additional contributions in the future," he added.


Oracle, headquartered in Redwood Shores, California, has arranged around a dozen acquisitions in the past year, most of them significantly smaller than its blockbuster, multibillion-dollar PeopleSoft and Siebel Systems buys. Other recent purchases include supply-chain logistics software maker Global Logistics Technologies, retail optimization software developer ProfitLogic, database performance enhancement technology company TimesTen, and a majority stake in Indian banking software vendor i-flex Solutions.

 

posted @ 2012-07-10 11:05 chen11-1 阅读(1161) | 评论 (0)编辑 收藏

IT人士遭遇早衰危机 对象难找老婆难陪

 IT 行业,说起来就让很多人心动。为啥?专出富豪呗。2012年胡润少壮派富豪榜中,IT 行业可是最“丰产”的行业。

  做 IT 的人却叫苦连连:“这个叫隔行如隔山……事实上我们并没有外界想的那样光鲜,你们上班的时候我们上班,你们下班的时候我们加班……年轻的时候不觉得,到了 30 岁,忽然有些力不从心的感觉了。”

  这似乎是很多“80后”IT 人士的心声,在工作了四五年之后,他们一方面面临身体、精力的瓶颈,另一方面,“90后”又在后面虎视眈眈。

 

  31岁的 IT 精英找不到女友

  刘先生今年 31 岁,是典型的 IT 男,大学一毕业就进入某网络公司的研发部,到现在已经是公司元老中的元老,也是研发部举足轻重的人物。

  按理说,像刘先生这样的真没什么好担忧的,位高权重,收入颇丰,但他依然觉得苦恼——做 IT 太费脑,加班时间太多。“我们公司加班非常多,忙到晚上三四点是常有的事情,我们每个人的桌下甚至都放了个躺椅,太累的时候就在办公室里睡会儿。”

  刘先生告诉记者,前几年,他倒是每天都充满干劲,天天加班都无所谓,但现在明显觉得吃不消了,连着加班几天,会有疲惫感,体力明显不如从前。

  “说 IT 行业是吃青春饭的,这话一点不假。我最近在电视剧《心术》里看到一句话,把人比喻为红苹果、青苹果、烂香蕉,说刚进医院的护士是红苹果,上了一年夜班的护士是青苹果,脸色发青,上了好几年夜班的护士是烂香蕉。我觉得自己就是根烂香蕉,脸色很差,整个人看起来就是tb亚健康状态的样子,甚至看起来比同龄人老。我现在已经有很多白头发了,可以预见,如果照这样的强度工作下去,到 45 岁,我出门,估计孩子们都得叫我爷爷——满头白发了。”

  刘先生的表弟今年考大学,IT 精英表哥一直是他崇拜的对象,填志愿时更是对表哥读过的学校的计算机系蠢蠢欲动,并立志要成为表哥那样的 IT 精英。刘先生赶忙劝说:“做 IT 很辛苦的,常常加班,还很费脑,你还是再考虑考虑,别的行业也可以。”

  因为老加班,刘先生连女朋友都没有。31岁了,有些同学的孩子都会打酱油了,他还是光棍一个,这也给他很大的压力。“以前没感觉,单身也挺快乐的,工作之余自己一个人瞎乐。过年的时候回去参加同学会,看到很多同学都带孩子来了,我还形单影只,忽然觉得有些迷茫。这几年的时间都贡献给工作了,连交女朋友的时间都没有。”

  刘先生告诉记者,在他们公司,他基本上也是做到头了:升职基本上已经遭遇天花板;再搞研发身体也吃不消了;转管理岗位,公司并不认同,也没有办法给他合适的位置。现在他打算自己出来创业,正好有几个做 IT 的朋友也都有创业打算,他们打算成立软件公司,专门开发手机软件,未来几年应该还是比较有前途的。

  年薪 60 万的 IT 男没时间陪家人

  有同样困扰的还有陈西(化名),他今年 30 岁,24岁大学毕业就从事 IT 业,跳了两次槽,目前年薪 60 万元,在杭州某家电子商务公司里做研发。

  陈西说,他其实很享受工作带来的成就感,但对于为工作而付出的无数个夜晚的加班感觉很无奈。“这几年关于过劳死的报道很多,很多正值壮年的人因为工作强度太大而猝死。我的一个同事,因为这几年工作太拼命,最近被查出来肝方面的毛病。我忽然觉得有些恐惧,怕这样的事情发生在我身上。我今年刚刚当了父亲,有了对龙凤胎,我想好好珍惜生命,看他们长大。我现在特别想过朝九晚五的生活,下班后就回家陪女儿,而不是对着冰冷的电脑加班。我也觉得很对不起我的妻子,她怀孕的时候产检都是自己去的,我太忙了。我现在想留出更多的时间给家人。”

  陈西告诉记者,他觉得自己在工作上也遇到了瓶颈,公司竞争很激烈,进来的“90后”都很有冲劲,像他们这种“前浪”,一不留神就会被拍死在沙滩上。“像我们做 IT 的,不可能一直做技术,这也是个吃青春饭的行当,一定要在三十左右技术达到一定程度的时候就转,转到非技术方面,管理或者是其他方面,或者创业。总之不能一直做,会有一个瓶颈,到达一定程度后就不会再往上涨了。我的同事、同学们都有这种感觉,到了 30 岁,就需要改变。”

  采访中,记者了解到,很多 IT 精英都有像刘先生和陈西这样的迷茫,长时间超负荷的工作,让他们没有自己的时间,很多 IT 男到 30 岁还打着光棍,虽然收入不菲,但因没有时间,并不受女生的欢迎。

  有些悲观的 IT 男甚至还萌生了 40 岁退休的想法,希望从此远

posted @ 2012-07-06 15:46 chen11-1 阅读(1289) | 评论 (1)编辑 收藏

二叉树三种非递归遍历的区别

1 #include <iostream>
  2
  3 #define MAXN  100
  4 using namespace stbd;
  5
  6
  7 struct BTNode
  8 {
  9     char tag;
10     BTNode *left;
11     BTNode *right;
12 };
13
14 class BTree
15 {
16 private:
17     BTNode **root;
18     void BuildBTree(BTNode **root);
19
20 public:
21     /*递归版本*/
22     void PreVisit(BTNode *root);
23     void InVisit(BTNode *root);
24     void PostVisit(BTNode *root);
25
26     /*非递归版本*/
27     void NR_PreVisit(BTNode *root);
28     void NR_InVisit(BTNode *root);
29     void NR_PostVisit(BTNode *root);
30
31     BTree(BTNode **r);
32     BTree();
33 };
34
35 BTree::BTree()
36 {
37
38 }
39
40 BTree::BTree(BTNode **r)
41 {
42     root = r;
43     /*
44 *root = new BTNode; 45     (*root)->left = NULL;
46 (*root)->right = NULL; 47     */
48     BuildBTree(root);
49 }
50
51 /*先序方式插入结点*/
52 void BTree::BuildBTree(BTNode **root)
53 {
54     char c;
55    
56     c = getchar();
57     if(c == '#')
58         *root=NULL;
59     else{
60         *root = new BTNode;
61         (*root)->tag = c;
62         BuildBTree(&(*root)->left);
63         BuildBTree(&(*root)->right);
64     }
65 }
66
67 void BTree::PreVisit(BTNode *root)
68 {
69     if(root!=NULL)
70     {
71         printf("%c ", root->tag );
72         PreVisit(root->left);
73         PreVisit(root->right);
74     }
75 }
76
77 void BTree::InVisit(BTNode *root)
78 {
79     if(root!=NULL)
80     {
81         InVisit(root->left);
82         printf("%c ", root->tag );
83         InVisit(root->right);
84     }
85 }
86
87 void BTree::PostVisit(BTNode *root)
88 {
89     if(root!=NULL)
90     {
91         PostVisit(root->left);
92         PostVisit(root->right);
93         printf("%c ", root->tag );
94     }
95 }
96
97 void BTree::NR_PreVisit(BTNode *root)
98 {
99     BTNode *s[MAXN];
100     int top=0;
101
102     while(top!=0 || root!=NULL)
103     {
104         while(root!=NULL)
105         {
106             s[top] = root;
107             printf("%c ", s[top++]->tag);
108             root = root->left;
109         }
110         if(top>0)
111         {
112             root = s[--top];
113             root = root->right;
114         }
115     }
116 }
117
118 void BTree::NR_InVisit(BTNode *root)
119 {
120     BTNode *s[MAXN];
121     int top=0;
122    
123     while(top!=0 || root!=NULL)
124     {
125         while(root!=NULL)
126         {
127             s[top++]=root;
128             root = root->left;
129         }
130         if(top>0)
131         {
132             root = s[--top];
133             printf("%c ", root->tag);
134             root = root->right;
135         }
136     }
137 }
138
139 void BTree::NR_PostVisit(BTNode *root)
140 {
141     BTNode *s[MAXN], *tmp=NULL;
142     int top=0;
143
144     while(top!=0 || root!=NULL)
145     {
146         while(root!=NULL)
147         {
148             s[top++]=root;
149             root=root->left;
150         }
151         if(top>0)
152         {
153             root = s[--top];
154
155             /*右孩子不存在或者已经访问过,root出栈并访问*/
156             if( (root->right == NULL) || (root->right == tmp) ) 
157             {
158                 printf("%c ", root->tag);
159                 tmp = root;        //保存root指针
160                 root=NULL;         //当前指针置空,防止再次入栈
161             }
162
163             /*不出栈,继续访问右孩子*/
164             else
165             {
166                 top++;             //与root=s[--top]保持平衡
167                 root = root->right;
168             }
169         }
170     }
171 }
172
173 int main()
174 {
175     BTNode *root=NULL;
176     BTree bt(&root);  //头指针的地址
177    
178     bt.NR_PreVisit(root);
179     printf("\n");
180     bt.NR_InVisit(root);
181     printf("\n");
182     bt.NR_PostVisit(root);
183     printf("\n");
184     return 0;
185 }
复制代码

先上代码,tb带NR(Non-recursive)的表示非递归遍历。

 

测试数据:

124#8##5##369###7##

 

表示的二叉树:

用windows自带的画图画的,的确是粗糙了点。。。

 

测试结果:

1 2 4 8 5 3 6 9 7
4 8 2 5 1 9 6 3 7
8 4 5 2 9 6 7 3 1

 

 

一、关于二叉树的建立

 

  首先要注意二叉树的创建过程,这里用的是先序方式递归插入结点,所以输入数据的时候,必须按照先序方式输入,

左结点或右结点为空的,用#表示。否则,输入不会有响应,因为递归过程还未结束,按CTRL+Z也没用。当然可以用其

他方式插入(如中序递归插入,后序递归插入等)。

 

二、三种非递归遍历的区别

 

  前序、中序和后序的递归遍历方式比较简单,这里就不讲了。而非递归的遍历方式,只需要用数组存储结点指针,模拟系统栈的工作机制就可以了。

先说先序非递归遍历,按照根-左-右的方式访问的话,需要将当前结点压栈(同时打印当前结点信息),直到左子树为空(内层while);然后出栈,访问

右结点;后面的操作就跟前面的一样了(外层while)。

  对于中序非递归遍历,可以看到代码结构几乎一模一样,只是打印结点信息的位置不同而已。这是因为中序遍历是左-根-右,这样前序和中序非

递归遍历(根-左和左-根都是压栈动作,且出栈动作的对象都是父节点)是一致的。

 

  对于后序非递归遍历,因为后序遍历是左-右-根,根的访问是在右孩子之后,而这意味着两种情况:

  1、右孩子不为空(继续访问右孩子);

  2、右孩子为空,从左孩子返回,则需要访问根结点。

  为了区分这两种情况(物理形式上从左孩子返回,还是从右孩子返回来访问根节点),对于右孩子的访问又需要判断根结点的右孩子是否为空或者已

访问过(右子树已遍历过)。除这两种情况外,都不应该访问根节点,而是要继续进入右子树。

  

三、补充说明

 

  在后序非递归遍历的else语句中top++纯粹是为了使栈保持平衡,因为对于2)继续访问右孩子这种情况,不需要出栈,而前面的root[--top]包含

出栈操作,以此保证栈的正确性(当然可以有其他的处理,这里也是考虑到三种非递归遍历方式的统一性)。

  两个while不会提高程序的时间复杂度,因为二叉树的结点个数是固定的,内层while是为了提高算法的逻辑性。

 

四、递归->非递归

 

  另外,今天实习看到一个老师写的非递归代码,非常棒,赞一个!他仅仅是将程序的返回地址和函数的形参、局部变量都保存起来,然后在退出时

还原现场;同样是非递归,但是这种方式更接近编译器的处理方式,同操作系统的任务切换也比较一致;所以这种处理方法为递归自动转换为非递归奠

定了基础。

  分享一下他当场编写的非递归的汉诺塔:

 

复制代码
  1 #include <stdio.h>
  2 #include <iostream>
  3 
  4 using namespace std ;
  5 
  6 #define  MAXSIZE  1000 
  7 
  8 struct SNode
  9 {
 10     int  n;
 11     char from ;
 12     char to;
 13     char aux ;
 14     int  label ;
 15 } ;
 16 
 17 struct STK
 18 {
 19     
 20     SNode  stack[MAXSIZE] ;
 21     int sp  ;
 22     STK()
 23     {
 24         sp = 0 ;
 25     };
 26     void push (int n,char from,char to,char aux, int label )
 27     {
 28         if ( sp>= MAXSIZE )
 29         {
 30             printf ( "STK is full!\n" ) ;
 31         }
 32         stack[sp].n = n ;
 33         stack[sp].from = from ;
 34         stack[sp].to = to ;
 35         stack[sp].aux = aux ;
 36         stack[sp++].label = label ;
 37     };
 38     SNode POP()
 39     {
 40         if ( sp <=0 )
 41         {
 42             printf ( "STK is empty!\n" ) ;
 43         }
 44         return stack[--sp] ;
 45     };
 46 } ;
 47 
 48 void move(int n,char from,char to,char aux)
 49 {
 50     if(n==1)
 51     {
 52         cout<<"将#1盘从"<<from<<"移到"<<to<<endl;
 53 }
 54     else
 55     {
 56          move(n-1,from,aux,to);
 57          cout<<"将#"<<n<<"盘从"<<from<<"移到"<<to<<endl;
 58          move(n-1,aux,to,from);
 59 }
 60 }
 61 
 62 
 63 void move_stk(int n,char from,char to,char aux)
 64 {
 65     STK stk ;
 66     char tmp;
 67 S1:
 68     if(n==1)
 69     {
 70         cout<<"将#1盘从"<<from<<"移到"<<to<<endl;
 71     }
 72     else
 73    {
 74     stk.push (n,from,to,aux,2 ) ;
 75     n = n-1 ;
 76     tmp = to ;
 77     to = aux ;  
 78     aux = tmp ;
 79     goto S1;
 80          // move(n-1,from,aux,to);
 81 S2:
 82          cout<<"将#"<<n<<"盘从"<<from<<"移到"<<to<<endl;
 83 
 84     stk.push (n,from,to,aux,3 ) ;
 85     n = n-1 ;
 86     tmp = from ;
 87     from = aux ;  
 88     aux = tmp ;
 89     goto S1;
 90          // move(n-1,aux,to,from);
 91 }
 92 S3:
 93     if ( stk.sp > 0 )
 94     {
 95         SNode sn = stk.POP() ;
 96         n = sn.n ;
 97         from = sn.from;
 98         to = sn.to ;
 99         aux = sn.aux ;
100         if  ( 1 == sn.label  )
101             goto S1;
102         else if ( 2 == sn.label )
103             goto S2;
104         else 
105             goto S3;        
106     }
107 }
108 
109 
110 
111 int main(int argc, char * argv[])
112 {
113     move ( 3,'A','B', 'C' );
114     printf ( "================================\n" ) ;
115     move_stk ( 3,'A','B', 'C' );
116 
117     return 0;
118 }

posted @ 2012-07-06 15:45 chen11-1 阅读(2092) | 评论 (0)编辑 收藏

客户端通过 HTTP 代理与 Telnet 服务器通信

最近遇到一个业务需求:客户端自动登录远程Telnet服务器,然后自动发出一系列指令,返回指令执行结果。

这里,我采用 TcpClient 来与远程服务器Telnet服务通信(默认端口:23)。这方面,网络上有不少的代码与文章。

完成之后,因需求变更,遇到了一个新的问题,就是客户机器需要通过 HTTP 代理来连接公网的 Telnetb 服务器。在这种情况,TcpClien 连接需要经过 HTTP 代理来与服务器通信。这方面代码几番求助度娘、谷歌无果。没办法,自己分析 HTTP 代理。

 

代理过程:

(1)客户机连接代理服务器;

(2)代理服务器请求连接Telnet服务器,Telnet服务器返回响应;

(3)代理服务器将Telnet返回响应传给客户端。

 

HTTP/1.0协议支持的请求方法有:GET、POST、PUT、DELETE、CONNECT等。同样HTTP代理服务器也这些请求方法。如:使用 GET/POST 方法代理访问网页等。

现在,要用的是 CONNECT 请求方法,去连接 Telnet 服务器。如下:

CONNECT xxx.xxx.xxx.xxx:23 HTTP/1.0

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)

xxx.xxx.xxx.xxx:23,为Telnet服务IP与端口。

 

接下来,就是利用HTTP代理,创建一个连接到Telnet服务器的 TcpCient 实例对象。

 

 


public TcpClient CreateTcpClient(string proxyHost, int proxyPort, string telnetHost, int telnetPort)
        {
            IPHostEntry entry = Dns.GetHostEntry(proxyHost);
            IPEndPoint ipEndPoint = new IPEndPoint(entry.AddressList[0], proxyPort);

            TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork);
            tcpClient.Connect(ipEndPoint); // 连接代理服务器.

            // CONNECT Telnet 服务器
            string connectCommand = string.Format("CONNECT {0}:{1} HTTP/1.0\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)\n\n", telnetHost, telnetPort);
            byte[] buffer = Encoding.ASCII.GetBytes(connectCommand);
            tcpClient.GetStream().Write(buffer, 0, buffer.Length);

            buffer = new byte[512];
            int received = tcpClient.GetStream().Read(buffer, 0, 512);
            string receivedText = Encoding.ASCII.GetString(buffer, 0, received);
            // 成功.
            if (receivedText.IndexOf("200") > -1)
                return tcpClient;
            return null;
        }
 

 这样的 TcpClient 通过代理与 Telnet 服务通信成功。

 

posted @ 2012-07-06 15:42 chen11-1 阅读(1258) | 评论 (1)编辑 收藏

用html+js+css做一个模拟键盘

 这个键盘用html+js+css搞出来的,做这个没什么目的,纯粹觉得好玩。

    现在暂时的功能有:

    1、可按键跟踪

    2、可大小写切换

    3、可鼠标点击输入

    4、可移动键盘位置

    可拓展功能有:

    1、可改变键盘大小

    2、可改变主题

    3、对某些按键添加事件

    4、结合html5的canvas弄个打字游戏啥的(想想就有趣^_^)

    ps(本人js和css都是菜鸟一枚,不喜可以喷,但请勿涉及家人)

 

html

 

keytBoard.js

View Code
复制代码
  1 //移动键盘
  2 function dragMing(idORclass1, idORclass2) {
  3     var obj = this; //这里的this是指dragMing对象么
  4     this.idORclass1 = idORclass1; //给dragMing的idORclass1赋值
  5     this.idORclass2 = idORclass2; //给dragMing的idORclass2赋值
  6     this.deltaX = 0;
  7     this.deltaY = 0;
  8 
  9     function dragStart(dragEvent) {
 10         obj.deltaX = dragEvent.clientX - $(obj.idORclass2).offset().left;
 11         obj.deltaY = dragEvent.clientY - $(obj.idORclass2).offset().top;
 12         $(document).bind("mousemove", dragMove);
 13         $(document).bind("mouseup", dragStop);
 14         dragEvent.preventDefault();
 15 
 16     }
 17     function dragMove(dragEvent) {
 18         $(obj.idORclass2).css({
 19             "left": (dragEvent.clientX - obj.deltaX) + "px",
 20             "top": (dragEvent.clientY - obj.deltaY) + "px"
 21         })
 22         dragEvent.preventDefault();
 23 
 24     }
 25     function dragStop() {
 26         $(document).unbind("mousemove", dragMove);
 27         $(document).unbind("mouseup", dragStop);
 28 
 29     }
 30 
 31     $(document).ready(function () {
 32         $(obj.idORclass1).bind("mousedown", dragStart);
 33 
 34     })
 35 }
 36 
 37 
 38 
 39 //绘制键盘
 40 function drawKeyboard(type) {
 41     $("#keyboardNum").empty();
 42     $("#keyboardLetterQ").empty();
 43     $("#keyboardLetterA").empty();
 44     $("#keyboardLetterZ").empty();
 45     $("#keyboardSpaceBar").empty();
 46 
 47     if (type == "lower") {
 48         var keyboardNum = { "192": "`", "49": "1", "50": "2", "51": "3", "52": "4", "53": "5", "54": "6", "55": "7", "56": "8", "57": "9", "48": "0", "189": "-", "187": "=", "8": "Backspace" };
 49         var keyboardLetterQ = { "81": "q", "87": "w", "69": "e", "82": "r", "84": "t", "89": "y", "85": "u", "73": "i", "79": "o", "80": "p", "219": "[", "221": "]" };
 50         var keyboardLetterA = { "20": "Caps Lock", "65": "a", "83": "s", "68": "d", "70": "f", "71": "g", "72": "h", "74": "j", "75": "k", "76": "l", "186": ";", "222": "'", "220": "\\" };
 51         var keyboardLetterZ = { "16": "Shift", "90": "z", "88": "x", "67": "c", "86": "v", "66": "b", "78": "n", "77": "m", "188": ",", "190": ".", "191": "/" };
 52         var keyboardSpaceBar = { "32": "Space", "": "Tim" };
 53         var key = "";
 54     }
 55     else {
 56         var keyboardNum = { "192": "~", "49": "!", "50": "@", "51": "#", "52": "$", "53": "%", "54": "^", "55": "&", "56": "*", "57": "(", "48": ")", "189": "_", "187": "+", "8": "Backspace" };
 57         var keyboardLetterQ = { "81": "Q", "87": "W", "69": "E", "82": "R", "84": "T", "89": "Y", "85": "U", "73": "I", "79": "O", "80": "p", "219": "{", "221": "}" };
 58         var keyboardLetterA = { "20": "Caps Lock", "65": "A", "83": "S", "68": "D", "70": "F", "71": "G", "72": "H", "74": "J", "75": "K", "76": "L", "186": ":", "222": "\"", "220": "|" };
 59         var keyboardLetterZ = { "16": "Shift", "90": "Z", "88": "X", "67": "C", "86": "V", "66": "B", "78": "N", "77": "M", "188": "<", "190": ">", "191": "?" };
 60         var keyboardSpaceBar = { "32": "Space", "": "Tim" };
 61         var key = "";
 62     }
 63     $.each(keyboardNum, function (key, value) {
 64         if (value != "Backspace") {
 65             key = $('<div class="simpleKey" name="key" key="' + key + '" value="' + value + '">' + value + '</div>');
 66             $("#keyboardNum").append(key);
 67         }
 68         else {
 69             key = $('<div class="backspaceKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
 70             $("#keyboardNum").append(key);
 71         }
 72     });
 73 
 74     $.each(keyboardLetterQ, function (key, value) {
 75         key = $('<div class="simpleKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
 76         $("#keyboardLetterQ").append(key);
 77     });
 78 
 79     $.each(keyboardLetterA, function (key, value) {
 80         if (value != "Caps Lock") {
 81             key = $('<div class="simpleKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
 82             $("#keyboardLetterA").append(key);
 83         }
 84         else {
 85             key = $('<div class="capslockKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
 86             $("#keyboardLetterA").append(key);
 87         }
 88     });
 89 
 90     $.each(keyboardLetterZ, function (key, value) {
 91         if (value != "Shift") {
 92             key = $('<div class="simpleKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
 93             $("#keyboardLetterA").append(key);
 94         }
 95         else {
 96             key = $('<div class="shiftKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
 97             $("#keyboardLetterA").append(key);
 98         }
 99     });
100 
101     $.each(keyboardSpaceBar, function (key, value) {
102         if (value != "Space") {
103             key = $('<div class="simpleKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
104             $("#keyboardSpaceBar").append(key);
105         }
106         else {
107             key = $('<div class="spaceKey" name="key"  key="' + key + '" value="' + value + '">' + value + '</div>');
108             $("#keyboardSpaceBar").append(key);
109         }
110     });
111 
112     addMouseClickEvent();
113 
114 
115 }
116 
117 //监听鼠标点击事件
118 function addMouseClickEvent() {
119     $("#close").click(function () {
120         closeKeyboard()
121     });
122 
123     $("div[name='key']").hover(function () {
124         $(this).css("background-color", "Gray");
125     }, function () {
126         $(this).css("background-color", "White");
127     }).click(function () {
128         var thisValue = $(this).attr("value");
129         var ID = $("#state").val();
130         switch (thisValue) {
131             case "": //"
132                 $("#" + ID).val($("#" + ID).val() + "\"");
133                 if ($("#shift").attr("checked") == true) {
134                     if ($("#capsLock").attr("checked") != true) {
135                         drawKeyboard("lower");
136                     }
137                     $("#shift").attr("checked", false);
138                 }
139                 break;
140             case "Shift":
141                 $("#shift").attr("checked", $("#shift").attr("checked") == true ? false : true);
142                 if ($("#shift").attr("checked") == true) {
143                     drawKeyboard("upper")
144                 }
145                 else {
146                     if ($("#capsLock").attr("checked") != true) {
147                         drawKeyboard("lower");
148                     }
149                 }
150                 break;
151             case "Caps Lock":
152                 $("#capsLock").attr("checked", $("#capsLock").attr("checked") == true ? false : true);
153                 $("#capsLock").attr("checked") == true ? drawKeyboard("upper") : drawKeyboard("lower");
154                 $("#shift").attr("checked", false)
155                 break;
156             case "Space":
157                 $("#" + ID).val($("#" + ID).val() + " ");
158                 break;
159             case "Backspace":
160                 $("#" + ID).val($("#" + ID).val().substring(0, $("#" + ID).val().length - 1));
161                 break;
162             default:
163                 $("#" + ID).val($("#" + ID).val() + thisValue);
164                 if ($("#shift").attr("checked") == true) {
165                     if ($("#capsLock").attr("checked") != true) {
166                         drawKeyboard("lower");
167                     }
168                     $("#shift").attr("checked", false);
169                 }
170 
171                 break;
172         }
173         $("#" + ID).focus();
174     });
175 }
176 
177 
178 //监听键盘事件
179 function addKeydownEvent() {
180     $("html").keydown(function (event) {
181         var realkey = String.fromCharCode(event.keyCode);
182 
183         //特殊键
184         if (event.keyCode == 32) { realkey = "Space" }
185         if (event.keyCode == 13) { realkey = "Enter" }
186         if (event.keyCode == 27) { realkey = " Esc" }
187         if (event.keyCode == 16) {
188             realkey = "Shift";
189             $("#shift").attr("checked", $("#shift").attr("checked") == true ? false : true);
190             if ($("#shift").attr("checked") == true) {
191                 drawKeyboard("upper")
192             }
193             else {
194                 if ($("#capsLock").attr("checked") != true) {
195                     drawKeyboard("lower");
196                 }
197             }
198         }
199         if (event.keyCode == 17) { realkey = " Ctrl" }
200         if (event.keyCode == 18) { realkey = "Alt" }
201         if (event.keyCode == 8) { realkey = "Backspace" }
202         if (event.keyCode == 20) { realkey = "Caps Lock"; $("#capsLock").attr("checked", $("#capsLock").attr("checked") == true ? false : true); $("#capsLock").attr("checked") == true ? drawKeyboard("upper") : drawKeyboard("lower"); }
203 
204 
205         $("div[name='key']").css("background-color", "White")
206         $("div[key=" + event.keyCode + "]").css("background-color", "Gray");
207 
208         //如果按了shif再按其他键并且这个键不是shif键盘变回小写
209         //如果capsLock选中了键盘就不用变回小写
210         if ($("#shift").attr("checked") == true && event.keyCode != 16) {
211             if ($("#capsLock").attr("checked") != true) {
212                 drawKeyboard("lower");
213             }
214             $("#shift").attr("checked", false);
215         }
216 
217     });
218 }
219 
220 //打开键盘
221 function openKeyboard(ID) {
222     $("#keyboard").css("visibility", "visible");
223     $("#state").val(ID);
224 }
225 
226 //关闭键盘
227 function closeKeyboard() {
228     $("#keyboard").css("visibility", "hidden")
229 }
230 
231 
232 $(function () {
233     var divKeyBoard = '<div id="keyboard" class="keyboard"><div id="keyboardHead"><div><input id="shift" type="checkbox"/>Shift</div><div><input id="capsLock" type="checkbox"/>Caps Lock</div><div id="close" style="border:1px solid black; float:right; width:20px; height:20px; cursor:pointer;"><img src="/Image/close.gif" style=" width:20px; height:20px"/></div></div><div id="keyboardNum"></div><div id="keyboardLetterQ"></div><div id="keyboardLetterA"></div><div id="keyboardLetterZ"></div><div id="keyboardSpaceBar"></div></div>';
234     $("body").append(divKeyBoard);
235     drawKeyboard("lower");
236     addKeydownEvent();
237     $("#keyboard").css("visibility", "hidden");
238     var drag = new dragMing("#keyboard", "#keyboard");
239 
240 })
241 
242       
1 .keyboard
2 {
3     width:800px;
4     height:300px;
5     text-align:center;
6     position:absolute;
7 }
8
9 .keyboard div
10 {
11     height:50px;
12 line-height:50px
13      float:left
14 }
15
16 #keyboardHead
17 {
18 width:800px;
19     position:relative;
20 }
21
22 #keyboardLetterQ
23 {
24     width:800px;
25     position:relative;
26     left:75px;
27 }
28
29 #keyboardSpaceBar 30 {
31     width:800px;
32     position:relative;
33     left:200px;
34     top:52px;
35 }
36
37 .simpleKey
38 {
39     width:50px;
40     border:1px solid black;    
41 }
42
43 .enterKey
44 {
45     width:100px;
46     height:100px;
47     border:1px solid black;        
48 }
49
50 .shiftKey
51 {
52     width:115px;
53     border:1px solid black;   
54 }
55
56 .backspaceKey
57 {
58     width:120px;
59     border:1px solid black;
60 }
61
62 .capslockKey
63 {
64     width:90px;
65     border:1px solid black;
66 }
67
68 .spaceKey
69 {
70     width:300px;
71     border:1px solid black;   
72 }
73
74 .keyboard div[name="key"]:hover{
75     background: Gray;
76 }
77
78 .keyboard div[name="key"]
79 {
80     cursor:pointer;
81 }

 

posted @ 2012-07-06 15:38 chen11-1 阅读(2499) | 评论 (1)编辑 收藏

正则表达式汇总

"^\d+$"  //非负整数(正整数 + 0
"^[0-9]*[1-9][0-9]*$"  //正整数
"^((-\d+)|(0+))$"  //非正整数(负整数 + 0
"^-[0-9]*[1-9][0-9]*$"  //负整数
"^-?\d+$"    //整数
"^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数
"^(-?\d+)(\.\d+)?$"  //浮点数
"^[A-Za-z]+$"  //26个英文字母组成的字符串
"^[A-Z]+$"  //26个英文字母的大写组成的字符串
"^[a-z]+$"  //26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串
"^\w+$"  //由数字、26个英文字母或者下划线组成的字符串
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url

整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$
只能输入数字:"^[0-9]*$"
只能输入n位的数字:"^\d{n}$"
只能输入至少n位的数字:"^\d{n,}$"
只能输入m~n位的数字:。"^\d{m,n}$"
只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"
只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"
只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"
只能输入非零的正整数:"^\+?[1-9][0-9]*$"
只能输入非零的负整数:"^\-[1-9][]0-9"*$
只能输入长度为3的字符:"^.{3}$"
只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"
只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"
只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"
只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"
只能输入由数字、26个英文字母或者下划线组成的字符串:"^\w+$"
验证用户密码:"^[a-zA-Z]\w{5,17}$"正确格式为:以字母开头,长度在6~18之间,tb只能包含字符、数字和下划线。
验证是否含有^%&'',;=?$\"等字符:"[^%&'',;=?$\x22]+"
只能输入汉字:"^[\u4e00-\u9fa5]{0,}$"
验证Email地址:"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"
验证InternetURL"^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"
验证电话号码:"^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$"正确格式为:"XXX-XXXXXXX""XXXX-XXXXXXXX""XXX-XXXXXXX""XXX-XXXXXXXX""XXXXXXX""XXXXXXXX"
验证身份证号(15位或18位数字):"^\d{15}|\d{18}$"
验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01""09""1""12"
验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01""09""1""31"。整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$
只能输入数字:"^[0-9]*$"
只能输入n位的数字:"^\d{n}$"
只能输入至少n位的数字:"^\d{n,}$"
只能输入m~n位的数字:。"^\d{m,n}$"
只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"
只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"
只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"
只能输入非零的正整数:"^\+?[1-9][0-9]*$"
只能输入非零的负整数:"^\-[1-9][]0-9"*$
只能输入长度为3的字符:"^.{3}$"
只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"
只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"
只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"
只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"
只能输入由数字、26个英文字母或者下划线组成的字符串:"^\w+$"
验证用户密码:"^[a-zA-Z]\w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。
验证是否含有^%&'',;=?$\"等字符:"[^%&'',;=?$\x22]+"
只能输入汉字:"^[\u4e00-\u9fa5]{0,}$"
验证Email地址:"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"
验证InternetURL"^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"
验证电话号码:"^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$"正确格式为:"XXX-XXXXXXX""XXXX-XXXXXXXX""XXX-XXXXXXX""XXX-XXXXXXXX""XXXXXXX""XXXXXXXX"
验证身份证号(15位或18位数字):"^\d{15}|\d{18}$"
验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01""09""1""12"
验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01""09""1""31"

posted @ 2012-07-05 13:26 chen11-1 阅读(1096) | 评论 (1)编辑 收藏

如何使自己的程序只运行一次

我介绍两个主流的方法。

方法一:使用Mutex来进行

1. 首先要添加如下的namespace:

using System.Threading;


2. 修改系统Main函数,大致如下:

bool bCreatedNew;

//Create a new mutex using specific mutex name
Mutex m =new Mutex( false, "myUniqueName", out bCreatedNew );
if( bCreatedNew )
Application.Run(new yourFormName());

如上面编码就可以了,要注意的一点是,在给Mutex起名字的时候,不要太简单,以tb防止和其他程序的Mutex重复,从而达不到所预想的效果。


方法二:使用Process来进行

1. 首先要添加如下的namespace:

using System.Diagnostics;
using System.Reflection;

2. 添加如下函数:

public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);

//Loop through the running processes in with the same name
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace("/", "//") == current.MainModule.FileName)
{
//Return the other process instance.
return process;
}
}
}

//No other instance was found, return null.
return null;
}

3. 修改系统Main函数,大致如下:

if( RunningInstance() == null )
Application.Run(new yourFormName());

如上面编码就可以了,要注意的一点是,在判断进程模块文件名是否相等这部分的代码,是可选的。如果当前的程序在文件系统中只存在一个的话,以上的方法是可以的;否则不要删除这部分的代码。


对比两种方法,就效率和简便性来说,前一种方法是最好的,也是我比较喜欢的;后一种方法,速度比较慢,其次通过ProcessName去系统中查寻,有可能查出来的Process并不是我想要得,虽说在后面加了文件目录判断,但是其含有潜在的问题(前面已经说出来)。不过,第一种方法也有缺陷,就是扩展性操作不方便,例如:让程序只运行一次,如果程序已经运行,把它弹出并显示到最前面。对于此,后一种方法就很有优势了。

 

posted @ 2012-07-05 13:25 chen11-1 阅读(761) | 评论 (0)编辑 收藏

JAVA获取CLASSPATH路径

ClassLoader 提供了两个方法用于从装载的类路径中取得资源:

        public URL  getResource (String name); 
        public InputStream  getResourceAsStream (String name); 

       这里name是资源的类路径,它是相对与“/”根路径下的位置。getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
       但是真正使用的不是ClassLoader的这两个方法,而是Class的 getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或 YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,不过根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader来做的,所以只需要使用 Class对象的这两个方法就可以了。

       因此,直接调用  this.getClass().getResourceAsStream(String name) ;获取流,静态化方法中则使用ClassLoader.getSystbemResourceAsStream (String name) ; 。

      下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。

1.this.getClass().getResource("")
得到的是当前类class文件的URI目录。不包括自己!
如:file:/D:/workspace/jbpmtest3/bin/com/test/

2.this.getClass().getResource("/")
得到的是当前的classpath的绝对URI路径
如:file:/D:/workspace/jbpmtest3/bin/

3.this.getClass() .getClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径
如:file:/D:/workspace/jbpmtest3/bin/

4.ClassLoader.getSystemResource("")
得到的也是当前ClassPath的绝对URI路径
如:file:/D:/workspace/jbpmtest3/bin/

5.Thread.currentThread().getContextClassLoader ().getResource("")
得到的也是当前ClassPath的绝对URI路径
如:file:/D:/workspace/jbpmtest3/bin/

6.ServletActionContext.getServletContext().getRealPath(“/”)
Web应用程序 中,得到Web应用程序的根目录的绝对路径。这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。
如:file:/D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/WebProject


注意点:

1.尽量不要使用相对于System.getProperty("user.dir")当前用户目录的相对路径。这是一颗定时炸 弹,随时可能要你的命。

2.尽量使用URI形式的绝对路径资源。它可以很容易的转变为URI,URL,File对象。

3.尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面ClassLoaderUtil类的public static URL getExtendResource(String relativePath)方法已经能够使用相对于classpath的相对路径定位所有位置的资源。

4.绝对不要使用硬编码的绝对路径。因为,我们完全可以使用ClassLoader类的getResource("")方法得到当前classpath的绝对路径。如果你一定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!

获得CLASSPATH之外路径的方法:
URL base = this.getClass().getResource(""); //先获得本类的所在位置,如/home/popeye/testjava/build/classes/net/ 
      String path = new File(base.getFile(), "……/……/……/"+name).getCanonicalPath(); //就可以得到/home/popeye/testjava/name

另外,如果从ANT启动程序,this.getClass().getResource("")取出来的比较怪,直接用JAVA命令行调试就可成功。

posted @ 2012-07-04 13:17 chen11-1 阅读(1175) | 评论 (0)编辑 收藏

通过 JavaScript 获取页面上的鼠标位置

用 JS 计算鼠标在页面上的位置并非难事, 只要把握好各浏览器的区别就可以轻易算出鼠标位置. (这是 DEMO)

视窗 (浏览器可视窗口) 就像是页面上的掩板开了一个洞. 滚动条可以改变页面和视窗之间的偏移量, 从而可以通过视窗看到页面的各个位置.
鼠标在页面上的位置 = 页面和视窗之间的偏移量 + 鼠标在视窗中的位置

图中的 cursorX 和 cursorY 分别是鼠标在视窗中的横向和纵向位置, scrollY 是tb页面和视窗之间的纵向距离. 当然, 当视窗宽度小于页面宽度的时候, 还会存在 scrollX. 那么鼠标在页面上的位置就是: (scrollX+cursorX, scrollY+cursorY)

IE 以外的浏览器 (本人测试过 Firefox 3.6, Opera 10.10, Chrome 4.1 和 Safari 4.0.4) 均可以通过 pageXOffset 和 pageYOffset 来获取页面和视窗间的横纵距离. 但 IE (本人测试过 IE6, IE7, IE8) 只能通过滚动位移来获取页面和视窗间的距离, 并存在一到两个像素的偏离.

以下是获取鼠标在页面上位置的代码实现. (这是 DEMO)

/**
 * 获取鼠标在页面上的位置
 * @param ev		触发的事件
 * @return			x:鼠标在页面上的横向位置, y:鼠标在页面上的纵向位置
 */
function getMousePoint(ev) {
	// 定义鼠标在视窗中的位置
	var point = {
		x:0,
		y:0
	};
 
	// 如果浏览器支持 pageYOffset, 通过 pageXOffset 和 pageYOffset 获取页面和视窗之间的距离
	if(typeof window.pageYOffset != 'undefined') {
		point.x = window.pageXOffset;
		point.y = window.pageYOffset;
	}
	// 如果浏览器支持 compatMode, 并且指定了 DOCTYPE, 通过 documentElement 获取滚动距离作为页面和视窗间的距离
	// IE 中, 当页面指定 DOCTYPE, compatMode 的值是 CSS1Compat, 否则 compatMode 的值是 BackCompat
	else if(typeof document.compatMode != 'undefined' && document.compatMode != 'BackCompat') {
		point.x = document.documentElement.scrollLeft;
		point.y = document.documentElement.scrollTop;
	}
	// 如果浏览器支持 document.body, 可以通过 document.body 来获取滚动高度
	else if(typeof document.body != 'undefined') {
		point.x = document.body.scrollLeft;
		point.y = document.body.scrollTop;
	}
 
	// 加上鼠标在视窗中的位置
	point.x += ev.clientX;
	point.y += ev.clientY;
 
	// 返回鼠标在视窗中的位置
	return point;
}

记得以前我写过一个减速滚动置顶的 JavaScript 方法, 也是通过计算视窗和页面高度来实现的, 其计算方法与本文的方法不同小异, 也可以搬过来用.

这几个月来, 专注前端项目的开发, 也算小有收获, 最近我会将一些积累作成文章分享于众. 以此作为铺垫, 由浅入深, 希望可以带出一些有用的内容.

posted @ 2012-07-04 13:15 chen11-1 阅读(175) | 评论 (0)编辑 收藏

JS的event对象使用总结

Event属性和方法:

1. type:事件的类型,如onlick中的click;

2. srcElement/target:事件源,就是发生事件的元素;

3. button:声明被按下的鼠标键,整数,1代表左键,2代表右键,4代表中键,如果按下多个键,酒把这些值加起来,所以3就代表左右键同时按下;(firefox中 0代表左键,1代表中间键,2代表右键)

4. clientX/clientY:事件发生的时候,鼠标相对于浏览器窗口可视文档区域的左上角的位置;(在DOM标准中,这两个属性值都不考虑文档的滚动情况,也就是说,无论文档滚动到哪里,只要事件发生在窗口左上角,clientX和clientY都是 0,所以在IE中,要想得到事件发生的坐标相对于文档开头的位置,要加上
document.body.scrollLeft和 documentb.body.scrollTop)

5. offsetX,offsetY/layerX,layerY:事件发生的时候,鼠标相对于源元素左上角的位置;

6. x,y/pageX,pageY:检索相对于父要素鼠标水平坐标的整数;

7. altKey,ctrlKey,shiftKey等:返回一个布尔值;

8. keyCode:返回keydown何keyup事件发生的时候按键的代码,以及keypress 事件的Unicode字符;(firefox2不支持 event.keycode,可以用 event.which替代 )

9. fromElement,toElement:前者是指代mouseover事件中鼠标移动过的文档元素,后者指代mouseout事件中鼠标移动到的文档元素;

10. cancelBubble:一个布尔属性,把它设置为true的时候,将停止事件进一步起泡到包容层次的元素;(e.cancelBubble = true; 相当于 e.stopPropagation();)

11. returnValue:一个布尔属性,设置为false的时候可以组织浏览器执行默认的事件动作;(e.returnValue = false; 相当于 e.preventDefault();)

12. attachEvent(),detachEvent()/addEventListener(),removeEventListener:为制定DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。在
attachEvent()事件执行的时候,tbhis关键字指向的是window对象,而不是发生事件的那个元素;

13. screenX、screenY:鼠标指针相对于显示器左上角的位置,如果你想打开新的窗口,这两个属性很重要;


一些说明:

1.  event代表事件的状态,例如触发event对象的元素、鼠标的位置及状态、按下的键等等;

2.  event对象只在事件发生的过程中才有效。
firefox里的event跟IE里的不同,IE里的是全局变量,随时可用;firefox里的要用参数引导才能用,是运行时的临时变量。
在IE/Opera中是window.event,在Firefox中是event;而事件的对象,在IE中是window.event.srcElement,在Firefox中是event.target,Opera中两者都可用。

3.  下面两句效果相同
var evt = (evt) ? evt : ((window.event) ? window.event : null);
var evt = evt || window.event; // firefox下window.event为null, IE下event为null

4.  IE中事件的起泡
IE中事件可以沿着包容层次一点点起泡到上层,也就是说,下层的DOM节点定义的事件处理函数,到了上层的节点如果还有和下层相同事件类型的事件处理函数,那么上层的事件处理函数也会执行。例如, div 标签包含了 a ,如果这两个标签都有onclick事件的处理函数,那么执行的情况就是先执行标签 a 的onclick事件处理函数,再执行 div 的事件处理函数。如果希望的事件处理函数执行完毕之后,不希望执行上层的 div 的onclick的事件处理函数了,那么就把cancelBubble设置为true即可。

posted @ 2012-07-04 13:14 chen11-1 阅读(885) | 评论 (0)编辑 收藏

仅列出标题
共20页: First 上一页 12 13 14 15 16 17 18 19 20 下一页