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改变时的值


<!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>

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


<?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) ;
    }
}
?>

three.js:在js目录下,发起ajax请求的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;
}
})

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


(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);

在做的过程中参考了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 实战


<!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>

update:2010.09.02

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

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


 var $j = jQuery;

2.插件开发的模式


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

3.最古老的方法


jQuery(document).ready(function($) {});

4.事件模型


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

ajax load的效果

最近开始学习jquery,利用jquery进行ajax的操作要方便的多了,下面的实例是一个简单的load效果。参考了 这篇文章。利用jquery发起 ajax请求,是很容易的,在参考了上面那篇文章后,就很容易就做一个demo出来。

这就是站在jquery的”肩上“的好处,基本就不用你做那些“底层”的工作了,这也是为什么jQuery号称“The Write Less, Do More”了!

demo的效果很简单,就是发起一个GET请求,在请求过程中显示loading的图片,服务器处理GET请求返回一段html代码(当然,在这里是没有返回html,实际会有的),然后loading状态消失,显示返回的html代码就ok。

这样就很简单的完成了一个ajax实例了。

相关代码如下:

html文件 ajaxload.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>
<title>ajax loading 效果</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
#loadingImg{
position:absolute;
width:300px;
top:0px;
left:50%;
margin-left:-120px;
text-align:center;
padding:7px 0 0 0;
font:bold 11px Arial, Helvetica, sans-serif;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#btn').click(function (){
//$('#selectclass').change( function (){
$.ajax({
url: 'ajaxload.php',
cache: false,
dataType: 'html',
type:'GET',
data: { name: $('#name').val(),selectclass: $('#selectclass').val()},
error: function(xhr) {
alert('Ajax request 發生錯誤');
},
success: function(response) {
$('#msg').html(response);
$('#msg').fadeIn();
}
});
});
$('#clean').click(function(){
$('#msg').html("");
// document.getElementById('msg').innerHTML = "";
});
$("#loadingImg").ajaxStart(function(){
$(this).show();
});
$("#loadingImg").ajaxStop(function(){
$(this).hide();
});
})
</script>
</HEAD>
<BODY>
<div id="loadingImg" style="display:none"><img src="loading.gif"> loading...</div>
<br><br><br>
<div align="center">
Enter your name <br>
<input type="text" id="name"> <br>
<select  id="selectclass">
<option  value="1">3.1</option>
<option  value="2">3.2</option>
<option value="3">3.3</option>
<option  value="4">3.4</option>
<option value="5">3.5</option>
</select><br>
<input type="button" value="send" id="btn">
<input type="button" value="reset" id="clean">

<br><br><br>
<div id="msg"> </div>
</div>
</BODY>
</HTML>

ajaxload.php

<?php
$myname = $_GET['name'];
$myclass = $_GET['selectclass'];
sleep(1); //为了 ajax loading效果,所以延迟5秒
echo "You input name is $myname <br>";
echo "You select class is $myclass <br>";
?>

ajax loading 时需要用到的一些图片可以在这里ajaxload图片库找到。

让jquery也和swfonject一样插入视频

大家正在做网站SEO时,都会用到swfobject来插入相关的flash的吧,然后再做SEO的内容。

那么如果是视频呢?可以像flash一样插入到网页中吗?

答案当然是可以的,因为我有jquery这样的利器。利用jquery我写了一个简单的扩展,像swfobject一样插入视频。

支持youku 和youtube的视频,支持自定义宽度。

代码如下 :


<!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>Video   Object</title>
<style media="screen" type="text/css">
#video{
    width:480px;
    height:400px;
    margin:0 auto;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="video.js"></script>
  <script type="text/javascript">
 $(function(){
           $("#video").videobject({id:'XMTQ4NTM5MjYw'});
     });
  </script>
</head>
<body>
<div  id="video">测试代码</div>
</body>
</html>

首先在页面引入jquery在google Libraaries API 上的库文件。然后就是我编写的一个扩展,该扩展的名字叫videobject,首先设置了扩展的默认设置,为了简化复杂的参数列表,jquery建议使用这种简化参数列表的形式,就是选项散列对象,即key/value,利用jquery自带的$.extend()函数合并参数,防止传递null或者 undefined的参数进来,在这里,我设置了flash,id,url,width,height等参数。

flash:需要插入的视频代码,可替换部分内容。

id:视频的id
如优酷的视频  查找 id 如

视频地址为http://player.youku.com/player.php/sid/XMTY0NzY4NjI4 /v.swf  则
即为id

url:此参数来区分是视频的类型,如优酷为youku,youtube为ytb

width:视频的宽度

height: 视频的高度

然后再声明了一个匿名函数(关于js匿名函数这里有比较好的分析),声明两个变量分别保存了,youku和youtube的视频通用的url地址,通过视频的id的长度来判断替换不同的视频的类型。然后就根据id来插入不同的<object>对象,最后返回当前的对象,先清空当前的div的内容,然后插入填充好了的<object>对象。

video.js 源代码


/*
 *videoobject version: 2.0 beta
 * 利用jquery 插入视频 支持自定义宽度和高度 支持优酷和youtube视频
 *用法$("div的id").videoobject(' 视频代码','类型代码','宽度','高度');
 *
 *视频代码:如http://player.youku.com /player.php/sid/XMTcwMDMxNTA4/v.swf  XMTcwMDMxNTA4即为视频代码 13位
 *默认视频的  宽度:480  高度:400
 *
 *支持 长地址  默认高度和宽度  支持优酷的自动播放
 *如优酷的视频  查找 id 如
 * 视频地址为http://player.youku.com/player.php/sid/XMTY0NzY4NjI4 /v.swf  则XMTY0NzY4NjI4即为id
 *调用方式:以youku为例
 *$("#video").videobject({id:'XMTY0NzY4NjI4'});
 *$("#video").videobject({id:'XMTY0NzY4NjI4',url:'youku'});
 *
 */

(function($){
        $.fn.videobject = function (callerSettings){
        var settings = $.extend({
            flash:'<object width="mywidth" height="myheight" type="application/x-shockwave-flash" data="myurl" id="youku_player" style="visibility: visible;"><param name="quality" value="high"><param name="allowScriptAccess" value="always"><param name="flashvars" value="playMovie=true&isAutoPlay=true"></object>',
            id:'XMTcwMDMxNTA4',
            url:'youku',
            width:'480',
            height:'400'
        },callerSettings||{});
        var showvideo = function(uri){
            var yk = 'http://player.youku.com/player.php/sid/myid/v.swf';
            //var yk ='http://static.youku.com/v/swf/qplayer.swf?VideoIDS=myid=&isAutoPlay=true&isShowRelatedVideo=false&embedid=-&showAd=0';
            var ytb ='http://www.youtube.com/v/myid&hl=en_US&fs=1&autoplay=1';
            // urlij жΪyouku or youtube
            if(uri.length ==13){settings.id = yk.replace(/myid/,uri);};//youku
            if(uri.length ==11){settings.id = ytb.replace(/myid/,uri);};//youtube
        return uri == 'youku'?settings.flash.replace(/myurl/,settings.id).replace(/mywidth/,settings.width).replace(/myheight/,settings.height):settings.flash.replace(/myurl/,settings.id).replace(/mywidth/,settings.width).replace(/myheight/,settings.height);
        };
return this.empty().html(showvideo(settings.id));
        }
})(jQuery);