jQuery 省市联动的效果

看到一个高手写了一个JS省份三级联动,看着我手痒痒,决定用jquery写一个,于是就开始漫长的json之旅

说起json,这个话就长了,反正大有取代xml的趋势,xml的复杂解析看着头大,想要详细了解json 请点击这里 这个是json中文官方网站的介绍。

好了,下面开始整体了,我做的这个省市是利用jquery发起ajax请求传递一个省的值,php文档获取这个值以后呢,输出相关的市级信息,格式当然是json的,然后就开始解析这个格式的信息,将其加载到select里面去,然后重复选择下面的县/区就可以了。

看图说话

刚开始是这样子的

jQuery 省市联动的效果 step1
jQuery 省市联动的效果 step1

选择湖北省以后呢,就加载下面的市级元素到色了传统里面的。

jQuery 省市联动的效果 step2
jQuery 省市联动的效果 step2

选择了合适的市以后呢,加载下面的区了。大致是这样的

jQuery 省市联动的效果 step3
jQuery 省市联动的效果 step3

相关的文件有四个:

目录结构

root

blog three.php
get  three.php
js three.js  jquery.selector.js

three.php:在blog的目录下,传递select改变时的值

[cce_php]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>三省联动</title>
<link rel="stylesheet" type="text/css" href="../css/style.css" />
<!--<script type="text/javascript" src="../js/jquery-1.3.2.min.js"></script>-->
<script  type="text/javascript"  src="../js/jquery-1.2.1.js"></script>
<script type="text/javascript" src="../js/jquery.selecter.js"></script>
<script type="text/javascript" src="../js/three.js"></script>
</head>

<body>
<div class="main">
<fieldset>
<legend>三省联动jquery版</legend>
<label for="province"></label>
<select id="province">
<option  value="1">湖北省</option>
<option  value="2">广东省</option>
</select>
<label for="city"></label>
<select id="city" name="city">
<option>武汉市</option>
<option>深圳市</option>
</select>
<label for="country"></label>
<select id="country">
<option>洪山区</option>
<option>罗湖区</option>
</select>
<div id="load"><img src="../images/loading.gif" width="18" height="18" /></div>
</fieldset>
</div>
</body>
</html>
[/cce_php]

three.php :在get目录下,获取相关的值,输出json信息

[cce_php]
<?php
//相关的市级信息,和区的信息
$arr2= array(
             array('value' => 'guangzhou','caption' => '广州市'),
             array('value' => 'guangzhou','caption' => '佛山市'),
             array('value' => 'guangzhou','caption' => '深圳市'),
             array('value' => 'guangzhou','caption' => '茂名市'),
             array('value' => 'guangzhou','caption' => '阳江市'),
             array('value' => 'guangzhou','caption' => '东莞市'),
             array('value' => 'guangzhou','caption' => '中山市')
);
$arr1= array(
             array('value' => 'wuhan','caption' => '武汉市'),
                   array('value' => 'wuhan','caption' => '宜昌市'),
                   array('value' => 'wuhan','caption' => '黄石市'),
                   array('value' => 'wuhan','caption' => '十堰市'),
                   array('value' => 'wuhan','caption' => '襄阳市'),
                   array('value' => 'wuhan','caption' => '武汉市'),
                   array('value' => 'wuhan','caption' => '荆州市'),
                   array('value' => 'wuhan','caption' => '孝感市'),
                   array('value' => 'wuhan','caption' => '黄冈市'),
                   array('value' => 'wuhan','caption' => '随州市')
);
$arr3 = array(array('value'=> 'hanyang','caption'=>'汉阳区'),
                    array('value'=> 'hanyang','caption'=>'洪山区'),
                    array('value'=> 'hanyang','caption'=>'青山区'),
                    array('value'=> 'hanyang','caption'=>'汉口区'),
                    array('value'=> 'hanyang','caption'=>'蔡甸区'),
                    array('value'=> 'hanyang','caption'=>'江夏区'),
                    array('value'=> 'hanyang','caption'=>'东湖开发区')
);
$arr4 = array(array('value'=> 'yuexiu','caption'=>'越秀区'),
                    array('value'=> 'yuexiu','caption'=>'荔湾区'),
                    array('value'=> 'yuexiu','caption'=>'海珠区'),
                    array('value'=> 'yuexiu','caption'=>'天河区'),
                    array('value'=> 'yuexiu','caption'=>'白云区'),
                    array('value'=> 'yuexiu','caption'=>'黄浦区'),
                    array('value'=> 'yuexiu','caption'=>'花都区')
);
//获取post过来的值,输出json格式的数据
if(isset($_POST['province'])){
$province = $_POST['province'];
if($province == "1"){
    echo json_encode($arr1) ;
    }elseif($province == "2"){
        echo  json_encode($arr2) ;
    }
}
if(isset($_POST['city'])){
    $city =$_POST['city'];
    if($city == "wuhan"){
    echo json_encode($arr3) ;
    }elseif($city == "guangzhou"){
        echo  json_encode($arr4) ;
    }
}
?>
[/cce_php]

three.js:在js目录下,发起ajax请求的js代码

[cce_js]
$(function (){
    $('#load').hide();
    $('#city').hide().change(function(){
        $('#country').show();
        });
    $('#country').hide();
    $('#province').change(function(){
                $('#country').hide();
        $.post('../get/three.php',{province:$('#province').val()},function(data){
                                          $('#city').loadSelect(json_decode(data));
                                          //$('#city').loadSelect(data);这样的载入会出现undefine的问题
                                          });
                                   });
    $('#city').change(function(){
        $.post('../get/three.php',{city:$('#city').val()},function(data){
                                          $('#country').loadSelect(json_decode(data));
                                          //$('#city').loadSelect(data);
                                          });
                                   });
    $('#load').ajaxStart(function(){
                                 $('#load').show();
                                $('#city').hide();
                                  });
    $('#load').ajaxStop(function(){
                                 $('#load').hide();
                                 $('#city').show();
                                 });
    //为了解决中文编码的问题
    function json_decode (str_json) {
    var json = this.window.JSON;
    if (typeof json === 'object' && typeof json.parse === 'function') {
        try {
            return json.parse(str_json);
        } catch(err) {
            if (!(err instanceof SyntaxError)) {
                throw new Error('Unexpected error type in json_decode()');
            }
            this.php_js = this.php_js || {};
            this.php_js.last_error_json = 4; // usable by json_last_error()
            return null;
        }
    }
    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
    var j;
    var text = str_json;
    cx.lastIndex = 0;
    if (cx.test(text)) {
        text = text.replace(cx, function (a) {
            return '\\u' +
            ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        });
    }
    if ((/^[\],:{}\s]*$/).
        test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
            replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
            replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
        j = eval('(' + text + ')');
        return j;
    }

    this.php_js = this.php_js || {};
    this.php_js.last_error_json = 4; // usable by json_last_error()
    return null;
}
})
[/cce_js]

jquery.selector.js 在js目录下,jquery 操作select的扩展

[cce_js]
(function($) {
    //清空select元素
  $.fn.emptySelect = function() {
    return this.each(function(){
      if (this.tagName=='SELECT') this.options.length = 0;
    });
  }
    //添加option选项
  $.fn.loadSelect = function(optionsDataArray) {
    return this.emptySelect().each(function(){
      if (this.tagName=='SELECT') {
        var selectElement = this;
        $.each(optionsDataArray,function(index,optionData){
          var option = new Option(optionData.caption,optionData.value);
          if ($.browser.msie) {
            selectElement.add(option);
          }
          else {
            selectElement.add(option,null);
          }
        });
      }
    });
  }
})(jQuery);
[/cce_js]

在做的过程中参考了jquery实战的相关jquery扩展,但是我却为此郁闷了好几天。情况是这样的,在jquery的扩展中,实现了一个loadSelect方法,但是呢,在实际的编写中呢,遇到json的编码问题,后来找到了这个解决jsnon中文编码的问题–json_decode函数 我是从这篇文章看 用js的json_decode解决json中文编码问题看到的,利用这个函数进行解码,解决的中文编码的问题,不然的话,在加载select的元素的option是会出现莫名其妙的undefined,这个在js已经注释了。有关json格式和php json格式的可参考这里

出现这样的情况原因初步认为是在ajax传递数据的过程中编码转换出现错误,我的全部的页面时utf-8,但是json的格式全部都是unicode编码,然后到了js那里,就晕了,出现undefine问题。

希望有更好的办法解决编码的问题,不过暂时这样搞定就好了。

sugarsync 使用报告

由于众所周知的原因dropbox被和谐了,所以才会有sugarsync的出现。跟dropbox一样强大的文件同步的东东,还有中文的界面哦, 经过一段时间的试用,感觉灰常的好。该软件会自动同步本地文件到服务器,然后同步到你的其他电脑上的本地文件夹,那么你还在用U盘为多台电脑手动进行文件 同步吗?你有忘记同步多台电脑的文件,到头来发现多态电脑的版本不一致的情形吗?你为了保持代码的同步,不得不去安装track,去svn吗?你有丢失过 code的经历吗就算你的代码真的被猫吃了,又不能找不回来了…..sugarsync就是解决你的这些难题的利器了。

该软件适合人群:适时的加班,需要将一些工作带回家完成,有多台电脑,如一台pc+一个笔记本。软件的设置非常简单,安装版本比较多,xp/mac/iphone/android,下载安装完成以后就可以管理自己的文件夹了,初始状态有2GB的免费空间,对我来说基本足够了,代码也就400M,设置好同步的文件夹就ok了,客户端会自动上传文件的,而且还有版本控制,有最新的3个版本让你选择。

其实我最好奇的就是如何实现xp和mac两台电脑之间的同步,因为我一般是在mac下面开发,但是回家只能用xp了,所以我对xp何mac如何保持对相同的文件的同步时很感兴趣的。

这个左边是我的mac 电脑,右边是xp本本来的

魔术公文包呢是sugarsync自带的同步文件,会在两台电脑的指定位置自动进行同步文件,XP下面 就是在你的电脑中“我的文档”目录下自动创建一个名为“魔术公文包”的文件夹,这个不是我想要的,因为我要同步的文件不在这里,我想自定义同步文件夹。

sugarsync 使用报告 step1
sugarsync 使用报告 step1

好了,经过一番摸索,终于被我找到了,E文不怎么样,在官网翻来覆去没找相关的文档。

首先了在xp设置好咬同步的文件夹,打开客户端登陆,点击  管理同步文件夹 -> 从本地计算机添加文件夹

添加你想同步的文件夹,好了以后呢,去另外一台电脑打开客户端登陆进去,这个我是在mac里面的。

就可以看到xp下面已经有一个同步的文件夹了(如下图),然后怎么样才能同步到我的mac下面去捏?

sugarsync 使用报告 step2
sugarsync 使用报告 step2

这个就很简单了,点击你想要同步的文件夹,按住鼠标拖到左边的电脑就行啦,嘿嘿,简单吧,

然后选择你要存储在mac电脑的那里,选择好位置以后呢,sugarsync会自动从服务器下载xp文件夹里面的文件啦

以后呢,在xp的所以更改全部会反映到mac,当然你在mac下面的更改也会全部都同步到xp下的,这样就方便多了吧!!!

sugarsync 使用报告 step3
sugarsync 使用报告 step3

这个是我的文件夹

现在进行注册的话,还有赠送250M的容量哦,这个当然是我推荐的啦,下面赠送新手教程和推广链接各一枚,需要的同学赶快下手啦!

sugarsync的 新手教程在这里

点击这里注册

jQuery 三种的习惯用法

jquery的三种习惯用法,先总结一下,参考书籍jQuery 实战

[cce_html]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>三种Jquery的ready方法</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
                           alert('the first method');
                           });//新手级别
$(function(){
           alert('the second method')
           });//专家级别,偶也喜欢这种方法,但是我是菜鸟......
(function(){
          alert('the three method');
          })(jQuery);//插件开发人员
//为么事three method会最先执行捏? 据说是由于 JavaScript 按照从内到外的顺序执行表达式,因此使用括号来强制执行已声明的函数。希望有高人来解答偶这个问题,好让偶彻底的明白是怎么回事。
</script>
</head>

<body>
</body>
</html>
[/cce_html]

update:2010.09.02

如果你想一直使用短代码,那么下面几种方法可以try一下。

1.将jQuery注册给其他的短代码

[cce_js] var $j = jQuery;[/cce_js]

2.插件开发的模式

[cce_js](function($) { /* some code that uses $ */ })(jQuery);;[/cce_js]

3.最古老的方法

[cce_js]jQuery(document).ready(function($) {});[/cce_js]

4.事件模型

[cce]jQuery(function($) { /* some code that uses $ */ });[/cce]