Ucenter 会员同步登录通讯原理

没有评论

2011 年 02 月 28 日 at 下午 4:25分类:PHP | Ucenter | UCHome | WEB开发

1,用户登录bbs,通过logging.php文件中,使用函数uc_user_login验证,如果验证成功,将调用函数uc_user_synlogin(位于uc_client下的client.php文件中),在这个函数中调用 uc_api_post(‘user’, ‘synlogin’, array(‘uid’=>$uid));之后向UC_API.’/index.php’传递了数据;这里的UC_API就是在config.inc.php中的定义的uc_server之URL地址

2,uc_server的index.php接受参数数据,获得model为user,action为synlogin,就调用control目录下的user.php类中的onsynlogin方法,通过foreach循环,以javascript的方式通知uc应用列表中的应用同步登录;即通过get方式传递给应用目录中api下的uc.php一些数据;

3,uc.php接收通知并处理get过来的数据,并在函数synlogin(位于uc.php中)通过函数_authcode加密数据(默认以UC_KEY作为密钥),用函数_setcookie设置cookie;

4,各个应用在适当的文件中用对应的密钥解码上面设置的cookie,得到用户id等数据;通过这个值来判断用户是否经过其它应用登录过;

以discuz举例:

一、用户登录检查与用户登录验证logging.php

在bbs的logging.php中如下代码段


} elseif($action == 'login') {

if($discuz_uid) {

$ucsynlogin = '';

showmessage('login_succeed', $indexname);

}

检查用户id变量$discuz_uid是否为空来判断,用户是否登录(包括从别的应用登录。)

如果用户从bbs登录,则在登录验证成功后通过如下代码:

$ucsynlogin = $allowsynlogin ? uc_user_synlogin($discuz_uid) : ”;

通知其它应用—-“用户已从bbs登录,请通知其它应用设置cookie”

(uc_server通过javascript调用方式向其它应用的api/uc.php传递数据)

可以在uc应用目录下新建一个名为test.php的文件,来模拟登录成功,请求uc_server通知其它应用。文件内容为:

<?php

include_once "config.inc.php";

include_once "./uc_client/client.php";

echo uc_user_synlogin(1);

echo "<pre>";

var_dump($_COOKIE);

echo "</pre>";

?>

<script type="text/javascript">

var obj=document.getElementsByTagName("script");

for(var i=0;i<obj.length-1;i++) {

document.write("<a href=\""+obj[i].src+"\">"+obj[i].src+"</a><hr>");

}

</script>

ps:这段测试代码还可以测试同步登录不好使的情况,具体使用方法,你可以思考一下(本文后面也有介绍),有问题可以在此文结尾发表评论与我讨论。

运行后,查看源代码即可看到javascript;
最主要的就是这段js代码串,通过这段js代码串去加载相应的应用api接口里面的uc.php文件,并且通过这串js代码传输了相关的数据到该文件中,以此来实现同步登陆的功能。
JS代码代码串如下:

这里要注意了:这些javascript的通知中是不包含用户登录的应用的。也就是说只”通知”用户未登录的应用,因为用户通过uc_server登录成功的当前应用,当然不需要uc_server再通知了。具体代码请参看:webroot\uc_server\control\user.php中的onsynlogin函数的这句:

if($app['synlogin'] && $app['appid'] != $this->app['appid'])

代码解释:

$app['synlogin']是uc应用是否允许同步登录

而且应用id不等于用户当前登录的应用id

$app数组就是uc_server\data\cache\apps.php中的数组$_CACHE['apps'];

$this->app就是用户登录的应用

二、接受其它应用的同步登录通知:

在discuz的api目录下的uc.php中的函数synlogin,在这里接受uc_server发送过来的“同步登录通知”,并设置discuz的cookie,在这个函数中你可以查看到cookie的加密密钥的“算法”;

如果你想看看uc_server发送过的的“通知”是什么数据,你可以这么做:

1,修改要接受通知的应用目录下的api\uc.php,在$action = $get['action'];代码下面添加如下代码:

echo "<pre>";var_dump($get);echo "</pre>";die("<hr>api\uc.php");

2,将上面建立的test.php文件放置在其它允许同步登录的应用目录下,并在浏览器中运行,然后点击页面中对应第一步的应用链接,即可看到uc_server“通知”给改应用的数据;

—————————分割线——————————-

function synlogin($get, $post)

在这个函数中通过_authcode函数,以密钥$discuz_auth_key加密了cookie;

在这里为了避免cookie名称冲突,在cookie名称(一般为:auth)前加了前缀($cookiepre),这个前缀也就是在config.inc.php中设置的那个cookie前缀值;

请看设置cookie的函数_setcookie:

(通过参数$prefix来判断是否对cookie名称添加前缀$cookiepre)

function _setcookie($var, $value, $life = 0, $prefix = 1) {

global $cookiepre, $cookiedomain, $cookiepath, $timestamp, $_SERVER;

setcookie(($prefix ? $cookiepre : '').$var, $value,

$life ? $timestamp + $life : 0, $cookiepath,

$cookiedomain, $_SERVER['SERVER_PORT'] == 443 ? 1 : 0);

}

密钥“算法”:

$discuz_auth_key= md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);

也就是不同用户加密cookie的密钥可能不同;

三、检查用户是否已登录(无论是那个应用下登录):

discuz的include目录中common.inc.php中有这样的代码:

$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);

list($discuz_pw, $discuz_secques, $discuz_uid) = empty($_DCOOKIE['auth']) ? array('', '', 0) : daddslashes(explode("\t", authcode($_DCOOKIE['auth'], 'DECODE')), 1);

这段代码就是解码在uc.php中用密钥($discuz_auth_key)加密的cookie值,以获得用户id($discuz_uid)这里的解密函数位于bbs\include\global.func.php中,虽然未给函数传递cookie密钥,但函数中通过全局变量$GLOBALS['discuz_auth_key'])获得密钥。

MySQL中concat函数

没有评论

2011 年 02 月 24 日 at 上午 11:42分类:MySQL | WEB开发

使用方法:
CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。
注意:
如果所有参数均为非二进制字符串,则结果为非二进制字符串。
如果自变量中含有任一二进制字符串,则结果为一个二进制字符串。
一个数字参数被转化为与之相等的二进制字符串格式;若要避免这种情况,可使用显式类型 cast, 例如:
SELECT CONCAT(CAST(int_col AS CHAR), char_col)
MySQL的concat函数可以连接一个或者多个字符串,如
mysql> select concat(’10′);
+————–+
| concat(’10′) |
+————–+
| 10 |
+————–+
1 row in set (0.00 sec)

mysql> select concat(’11′,’22′,’33′);
+————————+
| concat(’11′,’22′,’33′) |
+————————+
| 112233 |
+————————+
1 row in set (0.00 sec)

MySQL的concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL
mysql> select concat(’11′,’22′,null);
+————————+
| concat(’11′,’22′,null) |
+————————+
| NULL |
+————————+
1 row in set (0.00 sec)

MySQL中concat_ws函数
使用方法:
CONCAT_WS(separator,str1,str2,…)

CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。
注意:
如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。

如连接后以逗号分隔
mysql> select concat_ws(‘,’,’11′,’22′,’33′);

+——————————-+
| concat_ws(‘,’,’11′,’22′,’33′) |
+——————————-+
| 11,22,33 |
+——————————-+
1 row in set (0.00 sec)

和MySQL中concat函数不同的是, concat_ws函数在执行的时候,不会因为NULL值而返回NULL
mysql> select concat_ws(‘,’,’11′,’22′,NULL);
+——————————-+
| concat_ws(‘,’,’11′,’22′,NULL) |
+——————————-+
| 11,22 |
+——————————-+
1 row in set (0.00 sec)

MySQL中group_concat函数
完整的语法如下:
group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

基本查询

mysql> select * from aa;
+——+——+
| id| name |
+——+——+
|1 | 10|
|1 | 20|
|1 | 20|
|2 | 20|
|3 | 200 |
|3 | 500 |
+——+——+
6 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔(默认)

mysql> select id,group_concat(name) from aa group by id;
+——+——————–+
| id| group_concat(name) |
+——+——————–+
|1 | 10,20,20|
|2 | 20 |
|3 | 200,500|
+——+——————–+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,分号分隔

mysql> select id,group_concat(name separator ‘;’) from aa group by id;
+——+———————————-+
| id| group_concat(name separator ‘;’) |
+——+———————————-+
|1 | 10;20;20 |
|2 | 20|
|3 | 200;500 |
+——+———————————-+
3 rows in set (0.00 sec)

以id分组,把去冗余的name字段的值打印在一行,

逗号分隔

mysql> select id,group_concat(distinct name) from aa group by id;
+——+—————————–+
| id| group_concat(distinct name) |
+——+—————————–+
|1 | 10,20|
|2 | 20 |
|3 | 200,500 |
+——+—————————–+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序

mysql> select id,group_concat(name order by name desc) from aa group by id;
+——+—————————————+
| id| group_concat(name order by name desc) |
+——+—————————————+
|1 | 20,20,10 |
|2 | 20|
|3 | 500,200|
+——+—————————————+
3 rows in set (0.00 sec)

repeat()函数

用来复制字符串,如下’ab’表示要复制的字符串,2表示复制的份数

mysql> select repeat(‘ab’,2);

+—————-+
| repeat(‘ab’,2) |
+—————-+
| abab |
+—————-+

1 row in set (0.00 sec)

又如
mysql> select repeat(‘a’,2);

+—————+
| repeat(‘a’,2) |
+—————+
| aa |
+—————+
1 row in set (0.00 sec)

mysql向表中某字段后追加一段字符串:
update table_name set field=CONCAT(field,”,str)

mysql 向表中某字段前加字符串
update table_name set field=CONCAT(‘str’,field)

这个函数对你也许会有很大帮助哦!!

巧妙的使用数据库实现无限极分类

没有评论

2011 年 02 月 21 日 at 下午 4:39分类:PHP | WEB开发

利用数据库巧妙的实现无限极分类的效果
//实现无限分类

function shoptype_cache(){

	global $_SGLOBAL;
	$_SGLOBAL['shoptype'] = array();
	// 从数据库获取
	$query = $_SGLOBAL['db']-&gt;query(&quot;SELECT * FROM &quot; . tname(&quot;shop_type&quot;) . &quot; ORDER BY t_order&quot;);
	while($value = $_SGLOBAL['db']-&gt;fetch_array($query)){
		$_SGLOBAL['shoptype'][$value['t_id']] = $value;
	}
	//$_SGLOBAL['shoptype']是一个很平常的二维数组;
	$_SGLOBAL['shoptype']=treedata($_SGLOBAL['shoptype']);

}

//按照类别进行商品分类顺序的递归
//这一步的处理的是最核心的

function treedata($data, $fid = &quot;0&quot;) {
	global $arr8;
	foreach ( $data as $v ) {
		if ($v ['t_fid'] == $fid) {
			$arr8[] = $v;
			if (count ( $arr8 ) !== count ( $data )) {
				treedata ( $data, $v ['t_id'] );
			}
		}
	}
	return $arr8;
 }

效果图:

MySQL索引类型一览

没有评论

2011 年 02 月 17 日 at 上午 10:28分类:MySQL | WEB开发

索引是快速搜索的关键。MySQL索引的建立对于MySQL的高效运行是很重要的。下面介绍几种常见的MySQL索引类型。

在数据库表中,对字段建立索引可以大大提高查询速度。假如我们创建了一个 mytable表:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL ); 我们随机向里面插入了10000条记录,其中有一条:5555, admin。

在查找username=”admin”的记录 SELECT * FROM mytable WHERE username=’admin’;时,如果在username上已经建立了索引,MySQL无须任何扫描,即准确可找到该记录。相反,MySQL会扫描所有记录,即要查询10000条记录。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列。

MySQL索引类型包括:

(1)普通索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:

◆创建索引

CREATE INDEX indexName ON mytable(username(length)); 如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length,下同。

◆修改表结构

ALTER mytable ADD INDEX [indexName] ON (username(length)) ◆创建表的时候直接指定

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) ); 删除索引的语法:

DROP INDEX [indexName] ON mytable;

(2)唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

◆创建索引

CREATE UNIQUE INDEX indexName ON mytable(username(length)) ◆修改表结构

ALTER mytable ADD UNIQUE [indexName] ON (username(length)) ◆创建表的时候直接指定

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) );

(3)主键索引

它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) ); 当然也可以用 ALTER 命令。记住:一个表只能有一个主键。

(4)组合索引

为了形象地对比单列索引和组合索引,为表添加多个字段:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL ); 为了进一步榨取MySQL的效率,就要考虑建立组合索引。就是将 name, city, age建到一个索引里:

ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age); 建表时,usernname长度为 16,这里用 10。这是因为一般情况下名字的长度不会超过10,这样会加速索引查询速度,还会减少索引文件的大小,提高INSERT的更新速度。

如果分别在 usernname,city,age上建立单列索引,让该表有3个单列索引,查询时和上述的组合索引效率也会大不一样,远远低于我们的组合索引。虽然此时有了三个索引,但MySQL只能用到其中的那个它认为似乎是最有效率的单列索引。

建立这样的组合索引,其实是相当于分别建立了下面三组组合索引:

usernname,city,age usernname,city usernname 为什么没有 city,age这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引,下面的几个SQL就会用到这个组合索引:

SELECT * FROM mytable WHREE username=”admin” AND city=”郑州” SELECT * FROM mytable WHREE username=”admin” 而下面几个则不会用到:

SELECT * FROM mytable WHREE age=20 AND city=”郑州” SELECT * FROM mytable WHREE city=”郑州”

(5)建立索引的时机

到这里我们已经学会了建立索引,那么我们需要在什么情况下建立索引呢?一般来说,在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,因为MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引。例如:

SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username WHERE m.age=20 AND m.city=’郑州’ 此时就需要对city和age建立索引,由于mytable表的userame也出现在了JOIN子句中,也有对它建立索引的必要。

刚才提到只有某些时候的LIKE才需建立索引。因为在以通配符%和_开头作查询时,MySQL不会使用索引。例如下句会使用索引:

SELECT * FROM mytable WHERE username like’admin%’ 而下句就不会使用:

SELECT * FROM mytable WHEREt Name like’%admin’ 因此,在使用LIKE时应注意以上的区别。

(6)索引的不足之处

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:

◆虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

◆建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

(7)使用索引的注意事项

使用索引时,有以下一些技巧和注意事项:

◆索引不会包含有NULL值的列

只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

◆使用短索引

对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

◆索引列排序

MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

◆like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

◆不要在列上进行运算

select * from users where YEAR(adddate)<2007; 将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成 select * from users where adddate<‘2007-01-01’; ◆不使用NOT IN和<>操作

以上,就对其中MySQL索引类型进行了介绍。

的name属性在IE6,IE7中是只读属性

没有评论

2011 年 02 月 16 日 at 下午 5:35分类:PHP

input的name属性在IE6,IE7中是只读属性

input的name属性在IE6,IE7中是只读属性,只能使用以下方式进行创建input标签:
Js代码

var file_input = document.createElement("<input type='file' name='"+inputName+"' size='15' id='"+inputName+"' />");  

在Firefox中name属性是可读写的
Js代码

var file_input = document.createElement("input");  
 file_input.setAttribute("name",inputName);  //或用file_input.name =inputName;// IE下这个Name赋值不了.  
 file_input.type = "file";  
 file_input.size = 15;  
 file_input.id = inputName;  

如何建立Mysql索引

没有评论

2011 年 02 月 16 日 at 下午 3:55分类:MySQL | WEB开发

详见:1.http://www.360doc.com/content/10/1113/10/281812_68949035.shtml#

以下是为出现在where子句的字段建一个索引。为方便讲述,我们先建立一个如下的表。
  Code代码如下:
  CREATE TABLE mytable (
  id serial primary key,
  category_id int not null default 0,
  user_id int not null default 0,
  adddate int not null default 0
  );
  很简单吧,不过对于要说明这个问题,已经足够了。如果你在查询时常用类似以下的语句:
  SELECT * FROM mytable WHERE category_id=1;
  最直接的应对之道,是为category_id建立一个简单的索引:
  CREATE INDEX mytable_categoryid
  ON mytable (category_id);
  OK,搞定?先别高兴,如果你有不止一个选择条件呢?例如:
  SELECT * FROM mytable WHERE category_id=1 AND user_id=2;
  你的第一反应可能是,再给user_id建立一个索引。不好,这不是一个最佳的方法。你可以建立多重的索引。
  CREATE INDEX mytable_categoryid_userid ON mytable (category_id,user_id);
  注意到我在命名时的习惯了吗?我使用”表名_字段1名_字段2名”的方式。你很快就会知道我为什么这样做了。
  现在你已经为适当的字段建立了索引,不过,还是有点不放心吧,你可能会问,数据库会真正用到这些索引吗?测试一下就OK,对于大多数的数据库来说,这是很容易的,只要使用EXPLAIN命令:
  EXPLAIN
  SELECT * FROM mytable
  WHERE category_id=1 AND user_id=2;
  This is what Postgres 7.1 returns (exactly as I expected)
  NOTICE: QUERY PLAN:
  Index Scan using mytable_categoryid_userid on
  mytable (cost=0.00..2.02 rows=1 width=16)
  EXPLAIN
  以上是postgres的数据,可以看到该数据库在查询的时候使用了一个索引(一个好开始),而且它使用的是我创建的第二个索引。看到我上面命名的好处了吧,你马上知道它使用适当的索引了。

接着,来个稍微复杂一点的,如果有个ORDER BY字句呢?不管你信不信,大多数的数据库在使用order by的时候,都将会从索引中受益。
  SELECT * FROM mytable
  WHERE category_id=1 AND user_id=2
  ORDER BY adddate DESC;
  有点迷惑了吧?很简单,就象为where字句中的字段建立一个索引一样,也为ORDER BY的字句中的字段建立一个索引:
  CREATE INDEX mytable_categoryid_userid_adddate
  ON mytable (category_id,user_id,adddate);
  注意: “mytable_categoryid_userid_adddate” 将会被截短为
  ”mytable_categoryid_userid_addda”
  CREATE
  EXPLAIN SELECT * FROM mytable
  WHERE category_id=1 AND user_id=2
  ORDER BY adddate DESC;
  NOTICE: QUERY PLAN:
  Sort (cost=2.03..2.03 rows=1 width=16)
  -> Index Scan using mytable_categoryid_userid_addda
  on mytable (cost=0.00..2.02 rows=1 width=16)
  EXPLAIN
  看看EXPLAIN的输出,好象有点恐怖啊,数据库多做了一个我们没有要求的排序,这下知道性能如何受损了吧,看来我们对于数据库的自身运作是有点过于乐观了,那么,给数据库多一点提示吧。
  为了跳过排序这一步,我们并不需要其它另外的索引,只要将查询语句稍微改一下。这里用的是postgres,我们将给该数据库一个额外的提示–在ORDER BY语句中,加入where语句中的字段。这只是一个技术上的处理,并不是必须的,因为实际上在另外两个字段上,并不会有任何的排序操作,不过如果加入,postgres将会知道哪些是它应该做的。
  EXPLAIN SELECT * FROM mytable
  WHERE category_id=1 AND user_id=2
  ORDER BY category_id DESC,user_id DESC,adddate DESC;
  NOTICE: QUERY PLAN:
  Index Scan Backward using
  mytable_categoryid_userid_addda on mytable
  (cost=0.00..2.02 rows=1 width=16)
  EXPLAIN
  现在使用我们料想的索引了,而且它还挺聪明,知道可以从索引后面开始读,从而避免了任何的排序。

MySql count 去掉重复

没有评论

2011 年 02 月 15 日 at 下午 5:36分类:MySQL | WEB开发

1.

select count(distinct CName) from Course

2.

select count(CName) from (select distinct CName from Course) as temp

as可有可无。temp作为别名,若无则提示错误:1248 – Every derived table must have its own alias

JQuery拖动插件 $(‘…’).Drag()源码

没有评论

2011 年 02 月 15 日 at 下午 2:20分类:JavaScript | jQuery | WEB开发

http://www.aspxhome.com/download/javascript/20107/1429515.htm

功能配置参数:

  1. MouseDown、MouseMove、MouseUp:鼠标点下、拖动中、放开后的二次开发接口;格式如function(e){/*this*/},其中this等于拖动的目标对象。

  2. MoveObj:指定要拖动的目标JQuery对象,默认为触发鼠标点下事件的元素。该配置参数可用来实现模拟窗体中点标题栏拖动整个窗口对象的实例。

  3. OffMod:虚线框开关默认为false(也就是默认启用拖动虚线框防开鼠标后再对目标元素重新定位)。

  4. MoveInYMoveInX:是否将拖动对象锁定在Y轴或X轴上[true|false] 默认false,适用滑块调节功能,后面在实现DIV+CSS模拟滚动条时有用到。

  5. BoxObj:拖拽元素的容器对象,若指定则只能在该对象元素的占位范围内移动;仅当指定该属性时候第一组属性中的三个开发接口中可直接用this.InBox或this.OverBox来判断拖动目标是否在BoxObj内或是否已经触碰到了BoxObj

  6. BindInBox:绑定到容器中,默认为true;指定了属性BoxObj只是为了使用this.InBox或this.OverBox,而并不想将拖动目标元素的移动区域限制在BoxObj内部,那么将该属性设置为false就可以了。

jQuery处理键盘事件

没有评论

2011 年 02 月 15 日 at 上午 11:18分类:JavaScript | jQuery | WEB开发

这是一个jQ插件,用它基本上就可以实现类似于本地应用程序那样的快捷键系统。这个插件的名字叫js-hotkeys,名字很普通,但是功能却非常强大。这个插件可以做到全键盘的事件处理,包括F1-F12、Del/Home/PageUp、Tab等特殊键,以及Alt、Shift、Ctrl、Space等组合键,例如Ctrl+Shift+F1等等,而且支持Windows平台下的所有浏览器。
该jQ插件是基于另一个更强大的JS类库,具体可以参见这篇文章:Handling Keyboard Shortcuts in JavaScript。
该插件的调用方法非常简单,可以参考Google Code上的官方说明:点击这里。
也可以看小狮的翻译和总结,如下。
使用bind和unbind进行事件绑定,语法:
//绑定事件触发器
$(expression).bind(types,options, func);
//解除事件触发器
$(expression).unbind(types,options, func);
//绑定事件触发器$(expression).bind(types,options, func);//解除事件触发器$(expression).unbind(types,options, func);
expression:这个没啥好说的,指的是DOM对象。
types:触发器的类型(也就是在何时触发事件),目前支持keydown、keyup和keypress三种。
options:触发器参数。有两个,一个是combi,另一个是disableinInput。前者是指定要绑定的组合键,值是按键的Shortcode,后者是一个布尔值,表示是否屏蔽combi指定的按键,前提是expression必须是一个input或textarea对象,默认值是false。
func:当options中指定的combi触发时调用的函数。
例子:
view plaincopy to clipboardprint?
//在当前页面绑定Ctrl+a的快捷键,触发执行fn1()函数
$(document).bind(‘keydown’, ‘Ctrl+a’, fn1());
//在input.foo中输入的 ‘$’ 字符将自动替换为 ‘?’
$(‘input.foo’).bind(‘keyup’, ‘$’, function(){
this.value = this.value.replace(‘$’, ‘?’);
});
//在div.foo中按下Ctrl+a将不会再执行fn2()函数
$(‘div.foo’).unbind(‘keydown’, ‘Ctrl+a’, fn2());
//在当前页面的input和textarea中将无法输入’a'字符
$(document).bind(‘keydown’, {combi:’a', disableInInput: true}, fn3());
//在当前页面绑定Ctrl+a的快捷键,触发执行fn1()函数$(document).bind(‘keydown’, ‘Ctrl+a’, fn1());//在input.foo中输入的 ‘$’ 字符将自动替换为 ‘?’$(‘input.foo’).bind(‘keyup’, ‘$’, function(){this.value = this.value.replace(‘$’, ‘?’);});//在div.foo中按下Ctrl+a将不会再执行fn2()函数$(‘div.foo’).unbind(‘keydown’, ‘Ctrl+a’, fn2());//在当前页面的input和textarea中将无法输入’a'字符$(document).bind(‘keydown’, {combi:’a', disableInInput: true}, fn3());
不过小狮在测试disableInInput这个参数的时候总是不成功,不知道为什么。哪位知道的高手麻烦指教一下!小狮用的是Chrom测试的。
另外要注意组合键的Shortcode书写顺序是按照字母表顺序的,并且不区分大小写。

JS处理COOKIE的函数

没有评论

2011 年 02 月 14 日 at 下午 4:58分类:JavaScript | WEB开发

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>cookie处理函数练习(为我所写,非我所想:改善面向对象)</title>
<script language="JavaScript" type="text/javascript">
function addCookie(objName,objValue,objHours){//添加cookie
var str = objName + "=" + escape(objValue);
if(objHours > 0){//为0时不设定过期时间,浏览器关闭时cookie自动消失
var date = new Date();
var ms = objHours*3600*1000;
date.setTime(date.getTime() + ms);
str += "; expires=" + date.toGMTString();
}
document.cookie = str;
alert(str);
}

function getCookie(objName){//获取指定名称的cookie的值
var arrStr = document.cookie.split("; ");
for(var i = 0;i < arrStr.length;i ++){
var temp = arrStr[i].split("=");
if(temp[0] == objName) return unescape(temp[1]);
}  
}

function delCookie(name){//为了删除指定名称的cookie,可以将其过期时间设定为一个过去的时间
var date = new Date();
date.setTime(date.getTime() - 10000);
document.cookie = name + "=a; expires=" + date.toGMTString();
}

function allCookie(){//读取所有保存的cookie字符串
var str = document.cookie;
if(str == ""){
str = "没有保存任何cookie";
}
alert(str);
}

function $(m,n){
return document.forms[m].elements[n].value;
}

function add_(){
var cookie_name = $("myform","cookie_name");
var cookie_value = $("myform","cookie_value");
var cookie_expireHours = $("myform","cookie_expiresHours");
addCookie(cookie_name,cookie_value,cookie_expireHours);
}

function get_(){
var cookie_name = $("myform","cookie_name");
var cookie_value = getCookie(cookie_name);
alert(cookie_value);
}

function del_(){
var cookie_name = $("myform","cookie_name");
delCookie(cookie_name);
alert("删除成功");
}
function frameReload()
{
parent.show.location.reload();
}
</script>

</head>
<?php
if( $_GET['show'])
{
print_r( $_COOKIE);
exit;
}

?>
<body>
<form name="myform">
<div><label for="cookie_name">名称</label><input type="text" name="cookie_name" /></div>
<div><label for="cookie_value">取值</lable><input type="text" name="cookie_value" /></div>
<div><label for="cookie_expireHours">多少个小时过期</lable><input type="text" name="cookie_expiresHours" /></div>
<div>
<input type="button" value="添加该cookie" onclick="add_();frameReload();" />
<input type="button" value="读取所有cookie" onclick="allCookie();frameReload();" />
<input type="button" value="读取该名称cookie" onclick="get_();frameReload();" />
<input type="button" value="删除该名称cookie" onclick="del_();frameReload();" />
</div>
</form>
<hr />
<iframe name="show" id="show" src="./cookie.php?show=true" style="display:block;width:700px;height:300px;"></iframe>
</body>
</html>