以下是 jquery省市区县3级联动js代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="css.css" />
<link rel="stylesheet" href="form.css" />
<script src="kit.js"></script>
<!--[if IE]>
<script src="ieFix.js"></script>
<![endif]-->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-30210234-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
<script src="dom.js"></script>
<script src="event.js"></script>
<script src="TreeDict.js"></script>
<script src="math.js"></script>
<script src="form.js"></script>
<script src="combobox.js"></script>
<script src="suggestselect.js"></script>
<script src="list.js"></script>
<!--json data-->
<script src="json-data.js" charset="utf-8"></script>
</head>
<body>
<h1>国家省份城市联动</h1>
<ul>
<li>
<span> 省份 </span>
<select class="kitjs-form-suggestselect"></select>
<span> 市/县 </span>
<select class="kitjs-form-suggestselect"></select>
<span> 区 </span>
<select class="kitjs-form-suggestselect"></select>
</li>
</ul>
<script>
var a = $kit.els8cls($kit.ui.Form.ComboBox.Select.defaultConfig.transformCls), a1 = [];
for(var i = 0; i < a.length; i++) {
a1.push(a[i])
}
a = a1;
var b1 = new $kit.ui.Form.ComboBox.Select({
el : a[0],
data : (function() {
var provTreeDict = new TreeDict();
for(var prov in chinaJSON) {
provTreeDict.ad(prov, prov);
}
return provTreeDict;
})()
});
b1.transform();
b1.ev({
ev : 'change',
fn : function() {
var prov = chinaJSON[b1.inputEl.value];
if(prov == null) {
return;
}
var cityTree = new TreeDict();
for(var city in prov) {
cityTree.ad(city, city);
}
b2.inputEl.value = '';
b2.formEl.value = '';
b2.config.data = cityTree;
b2.list.buildList(cityTree.search(''));
}
});
var b2 = new $kit.ui.Form.ComboBox.Select({
el : a[1],
data : undefined
});
b2.transform();
b2.ev({
ev : 'change',
fn : function() {
var city = chinaJSON[b1.inputEl.value][b2.inputEl.value];
if(city == null) {
return;
}
var districtTree = new TreeDict();
for(var district in city) {
districtTree.ad(district, city[district]);
}
b3.inputEl.value = '';
b3.formEl.value = '';
b3.config.data = districtTree;
b3.list.buildList(districtTree.search(''));
}
});
var b3 = new $kit.ui.Form.ComboBox.Select({
el : a[2],
data : undefined
});
b3.transform();
</script>
<br><br><br><br><br><br><br><br>
</body>
</html>
JS代码(dom.js):
/** * Dom扩展 * @class $Kit.Dom * @requires kit.js * @see <a href="https://github.com/xueduany/KitJs/blob/master/KitJs/src/js/dom.js">Source code</a> */
$Kit.Dom = function(){
//}
$kit.merge($Kit.Dom.prototype,/** * @lends $Kit.Dom.prototype */
{
/** * 根据tagName查找父元素 * @param{
Element}
* @param{
String}
* @param{
Element}
[topEl] 到topEl停止查找 * @return{
Element|Null}
*/
parentEl8tag:function(el,tagName,topEl){
var topEl = topEl || document.body;
return $kit.parentEl(el,function(p){
if(p.tagName && p.tagName.toLowerCase() == tagName.toLowerCase()){
return true;
}
if(p == topEl){
return false;
}
}
,topEl);
}
,/** * 根据className查找父元素 * @param{
Element}
* @param{
String}
* @param{
Element}
[topEl] 到topEl停止查找 * @return{
Element|Null}
*/
parentEl8cls:function(el,cls,topEl){
var topEl = topEl || document.body;
return $kit.parentEl(el,function(p){
if($kit.hsCls(p,cls)){
return true;
}
if(p == topEl){
return false;
}
}
,topEl);
}
,/** * 注入script块 * @param{
Object}
config * @param{
String}
config.id 注入script的id,自定义,只要与现有dom里面的元素id不相同即可 * @param{
String}
[config.url] 注入script的加载url * @param{
String}
[config.text] 注入script的script内容 * @param{
String}
[config.then] 注入script的加载完毕的回调方法 * @param{
String}
[config.scope] 注入script的回调方法的this指针 * @return{
Element}
script */
injectJs:function(){
if(arguments.length == 1){
var config = arguments[0];
if(config.id && $kit.el8id(config.id)){
return;
}
config.id = config.id || $kit.onlyId();
var where = config.where || window.document.body;
var script = document.createElement('script');
$kit.attr(script,'type','text/javascript');
if(config.id){
$kit.attr(script,'id',config.id);
}
if(!$kit.isEmpty(config.url)){
script.src = config.url;
if(!$kit.isEmpty(config.then)){
var scope = config.scope || window;
script.onload = function(){
config.then.call(scope,script);
}
}
}
else if(!$kit.isEmpty(config.text)){
script.innerHTML = config.text;
if(!$kit.isEmpty(config.then)){
setTimeout(function(){
config.then.call(scope,script);
}
,0);
}
}
where.appendChild(script);
return script;
}
}
,/** * 注入css * @param{
Object}
config * @param{
String}
config.id 注入css的id,自定义,只要与现有dom里面的元素id不相同即可 * @param{
String}
[config.url] 注入css的url * @param{
String}
[config.text] 如果没有url的话,写入style的文本 * @return{
Element}
css */
injectCss:function(){
if(arguments.length == 1){
var config = arguments[0];
if(config.id && $kit.el8id(config.id)){
return;
}
// Takes a string of css,inserts it into a `<style>`,then injects it in at the very top of the `<head>`. This ensures any user-defined styles will take precedence.var where = config.where || document.getElementsByTagName('head')[document.getElementsByTagName('head').length - 1];
var css;
if(!$kit.isEmpty(config.url)){
css = document.createElement('link');
config.id && $kit.attr(css,'id',config.id);
$kit.attr(css,{
rel:'stylesheet',href:config.url}
);
}
else if(!$kit.isEmpty(config.text)){
css = document.createElement('style');
config.id && $kit.attr(css,'id',config.id);
$kit.attr(css,'type','text/css');
css.innerHTML = config.text;
}
if(css){
$kit.insEl({
pos:'last',what:css,where:where}
);
}
return css;
}
}
,/** * 删除所有样式 * @param{
String}
* @param{
Element}
*/
rmClsAll:function(cls,top){
var a = $kit.el8cls(cls,top);
while(a){
$kit.rmCls(a,cls);
a = $kit.el8cls(cls,top);
}
}
,/** * 通过className前缀取className * @param{
Element}
* @param{
String}
* @return{
NodeList||Null}
*/
getClassNameByPrefix:function(el,prefixCls){
var clsAry = el.className.split(/\s+/);
var re = null;
if(clsAry && clsAry.length){
$kit.each(clsAry,function(o){
if(o.indexOf(prefixCls) == 0){
re = o;
return false;
}
}
);
}
return re;
}
,/** * innerText * @param{
Element}
* @param{
String}
[text] * @return{
String|Null}
*/
text:function(el,text){
if(el != null && 'innerText' in el){
if(text){
el.innerText = text;
}
else{
return el.innerText;
}
}
else{
if(text){
el.textContent = text;
}
else{
return el.textContent;
}
}
}
,/** * innerHTML * @param{
Element}
* @param{
String}
[html] * @return{
String|Null}
*/
html:function(el,html){
if(html){
if(el != null && 'innerHTML' in el){
el.innerHTML = html;
}
}
else{
return el.innerHTML;
}
}
,/** * clone a node * @param{
Element}
* @return{
Element}
*/
clone:function(node){
if(document.createElement("nav").cloneNode(true).outerHTML !== "<:nav></:nav>"){
return node.cloneNode(true);
}
else{
var fragment = document.createDocumentFragment(),//doc = fragment.createElement ? fragment:document;
doc.createElement(node.tagName);
var div = doc.createElement('div');
fragment.appendChild(div);
div.innerHTML = node.outerHTML;
return div.firstChild;
}
}
,/** * height * @param{
Element}
* @param{
Number}
[value] * @return{
Number|Null}
*/
height:function(node,value){
var me = this;
if(node != null){
if(value == null){
return $kit.offset(node).height;
}
if(document.compatMode == "BackCompat"){
node.style.height = value;
}
else{
node.style.height = value//- ($kit.css(node,'border-top-width') || 0)//- ($kit.css(node,'border-bottom-width') || 0)//- ($kit.css(node,'padding-top-width') || 0)//- ($kit.css(node,'padding-bottom-width') || 0)//;
}
}
return $kit.viewport().clientHeight;
}
,/** * width * @param{
Element}
* @param{
Number}
[value] * @return{
Number|Null}
*/
width:function(node,value){
var me = this;
if(node != null){
if(value == null){
return $kit.offset(node).width;
}
if(document.compatMode == "BackCompat"){
node.style.width = value;
}
else{
node.style.width = value//- ($kit.css(node,'border-left-width') || 0)//- ($kit.css(node,'border-right-width') || 0)//- ($kit.css(node,'padding-left-width') || 0)//- ($kit.css(node,'padding-right-width') || 0)//;
}
}
return $kit.viewport().clientHeight;
}
,/** * height + padding * @param{
Element}
* @return{
Number}
*/
innerHeight:function(node){
var me = this;
if(document.compatMode == "BackCompat"){
return $kit.css(node,'height') - ($kit.css(node,'border-top-width') || 0) - ($kit.css(node,'border-bottom-width') || 0);
}
return $kit.css(node,'height') + ($kit.css(node,'padding-top-width') || 0) - ($kit.css(node,'padding-bottom-width') || 0);
}
,/** * width + padding * @param{
Element}
* @return{
Number}
*/
innerWidth:function(node){
var me = this;
if(document.compatMode == "BackCompat"){
return $kit.css(node,'width') - ($kit.css(node,'border-left-width') || 0) - ($kit.css(node,'border-right-width') || 0);
}
return $kit.css(node,'width') + ($kit.css(node,'padding-left-width') || 0) - ($kit.css(node,'padding-right-width') || 0);
}
,/** * height + padding + border * @param{
Element}
* @return{
Number}
*/
outerHeight:function(node){
var me = this;
if(document.compatMode == "BackCompat"){
return $kit.css(node,'height');
}
return $kit.css(node,'height') + ($kit.css(node,'padding-top-width') || 0) - ($kit.css(node,'padding-bottom-width') || 0)//+ ($kit.css(node,'border-top-width') || 0) + ($kit.css(node,'border-bottom-width') || 0);
}
,/** * width + padding + border * @param{
Element}
* @return{
Number}
*/
outerWidth:function(node){
var me = this;
if(document.compatMode == "BackCompat"){
return $kit.css(node,'width');
}
return $kit.css(node,'width') + ($kit.css(node,'padding-left-width') || 0) - ($kit.css(node,'padding-right-width') || 0)//+ ($kit.css(node,'border-left-width') || 0) + ($kit.css(node,'border-right-width') || 0);
}
,/** * 包围一个html * @param{
Element}
* @param{
String}
*/
wrap:function(node,html){
if($kit.isNode(html)){
//}
else if($kit.isStr(html)){
html = $kit.newHTML(html).childNodes[0];
}
else{
return;
}
$kit.insEl({
where:node,what:html,pos:'before'}
);
html.appendChild(node);
return html;
}
,/** * 序列化form元素 * @param{
Element}
* @param{
String}
* @return{
String}
*/
serialize:function(form){
if($kit.isNode(form)){
if(form.tagName.toLowerCase() == 'form'){
var formEls ={
}
;
$kit.each($kit.el('input',form),function(o){
if(o.type && o.type.toString.toLowerCase() == 'text'){
formEls[o.name] = o.value;
}
else if(o.type && o.type.toString().toLowerCase() == 'radio'){
if(o.checked){
formEls[o.name] = o.value;
}
}
else if(o.type && o.type.toString().toLowerCase() == 'checkbox'){
if(o.checked){
if(!$kit.isAry(formEls[o.name])){
formEls[o.name] = [formEls[o.name]];
}
formEls[o.name].push(o.value);
}
}
}
);
$kit.each($kit.el('textarea',form),function(o){
formEls[o.name] = o.value;
}
);
$kit.each($kit.el('select',form),function(o){
formEls[o.name] = o.options[o.selectedIndex].value;
}
);
var re = [];
for(var key in formEls){
if($kit.isAry(formEls[key])){
re.push(key + '=' + encodeURIComponent(formEls[key].join(',')));
}
else{
re.push(key + '=' + encodeURIComponent(formEls[key]));
}
}
return re.join('');
}
return form.name + '=' + encodeURIComponent($kit.val(form));
}
}
,/** * 计算元素相对于他的offsetParent的偏移 * @param{
Element}
* @return{
Number}
top 距离顶部 * @return{
Number}
left 距离左边 * @return{
Number}
height 高度 * @return{
Number}
width 宽度 * @return{
Number}
bottom 底部距离顶部 * @return{
Number}
right 右边距离最左边 * @return{
Number}
middleTop 中间距离顶部 * @return{
Number}
middleLeft 中间距离最左边 */
position:function(el){
var me = this;
if($kit.isEmpty(el)){
return;
}
var top = el.offsetTop,//left = el.offsetLeft,//width = el.offsetWidth,//height = el.offsetHeight;
return{
top:top,left:left,width:width,height:height,bottom:top + height,right:left + width,middleTop:top + height / 2,middleLeft:left + width / 2}
}
,/** * 计算元素相对于他的可视区的偏移 * @param{
Element}
* @return{
Number}
top 距离顶部 * @return{
Number}
left 距离左边 * @return{
Number}
height 高度 * @return{
Number}
width 宽度 * @return{
Number}
bottom 底部距离顶部 * @return{
Number}
right 右边距离最左边 * @return{
Number}
middleTop 中间距离顶部 * @return{
Number}
middleLeft 中间距离最左边 */
clientOffset:function(el){
var me = this;
if($kit.isEmpty(el)){
return;
}
var offset = $kit.offset(el);
var viewport = $kit.viewport();
return{
top:offset.top - viewport.scrollTop,left:offset.left - viewport.scrollLeft,width:offset.width,height:offset.height,bottom:offset.bottom - viewport.scrollTop,right:offset.right - viewport.scrollLeft,middleTop:offset.top - viewport.scrollTop + offset.height / 2,middleLeft:offset.left - viewport.scrollLeft + offset.width / 2}
}
,/** * 获取当一个元素居中的时候,他相对于doc绝对值的top,bottom,left,right等等 * @param{
Element}
* @return{
Number}
top 距离顶部 * @return{
Number}
left 距离左边 * @return{
Number}
height 高度 * @return{
Number}
width 宽度 * @return{
Number}
bottom 底部距离顶部 * @return{
Number}
right 右边距离最左边 * @return{
Number}
middleTop 中间距离顶部 * @return{
Number}
middleLeft 中间距离最左边 */
offsetCenter:function(el){
var me = this;
var viewport = $kit.viewport();
var offset = $kit.offset(el);
return{
top:viewport.clientHeight / 2 + viewport.scrollTop - offset.height / 2,left:viewport.clientWidth / 2 + viewport.scrollLeft - offset.width / 2,right:viewport.clientWidth / 2 + viewport.scrollLeft + offset.width / 2,bottom:viewport.clientHeight / 2 + viewport.scrollTop + offset.height / 2,middleTop:viewport.clientHeight / 2 + viewport.scrollTop,middleLeft:viewport.clientWidth / 2 + viewport.scrollLeft}
}
,/** * 获取当一个元素居中的时候,他相对于可视区域的top,bottom,left,right等等 * @param{
Element}
* @return{
Number}
top 距离顶部 * @return{
Number}
left 距离左边 * @return{
Number}
height 高度 * @return{
Number}
width 宽度 * @return{
Number}
bottom 底部距离顶部 * @return{
Number}
right 右边距离最左边 * @return{
Number}
middleTop 中间距离顶部 * @return{
Number}
middleLeft 中间距离最左边 */
clientOffsetCenter:function(el){
var me = this;
var viewport = $kit.viewport();
var offset = $kit.offset(el);
return{
top:(viewport.clientHeight / 2 - offset.height / 2),left:(viewport.clientWidth / 2 - offset.width / 2),right:(viewport.clientWidth / 2 + offset.width / 2),bottom:(viewport.clientHeight / 2 + offset.height / 2),middleTop:(viewport.clientHeight / 2),middleLeft:(viewport.clientWidth / 2)}
}
,/** * 获取当一个元素居中的时候,他相对于可视区域的top,bottom,left,right等等 * @param{
Element}
* @return{
Number}
top 距离顶部 * @return{
Number}
left 距离左边 * @return{
Number}
height 高度 * @return{
Number}
width 宽度 * @return{
Number}
bottom 底部距离顶部 * @return{
Number}
right 右边距离最左边 * @return{
Number}
middleTop 中间距离顶部 * @return{
Number}
middleLeft 中间距离最左边 */
clientPos:function(el){
var me = this;
var viewport = $kit.viewport();
var offset = $kit.offset(el);
return{
top:viewport.clientHeight / 2 + viewport.scrollTop - offset.height / 2,left:viewport.clientWidth / 2 + viewport.scrollLeft - offset.width / 2,right:viewport.clientWidth / 2 + viewport.scrollLeft + offset.width / 2,bottom:viewport.clientHeight / 2 + viewport.scrollTop + offset.height / 2,middleTop:viewport.clientHeight / 2 + viewport.scrollTop,middleLeft:viewport.clientWidth / 2 + viewport.scrollLeft}
}
,/** * 交换两个element的位置 */
switchPos:function(origin,target){
var targetPos;
if(target.previousSibling){
targetPos ={
pos:'after',where:target.previousSibling}
}
else{
targetPos ={
pos:'first',where:target.parentNode}
}
$kit.insEl({
pos:'after',where:origin,what:target}
);
$kit.insEl($kit.merge({
what:origin}
,targetPos));
}
}
);
/** * $Kit.Dom的实例,直接通过这个实例访问$Kit.Dom所有方法 * @global * @name $kit.dom * @alias $kit.d * @type $Kit.Dom */
$kit.dom = $kit.d = new $Kit.Dom();
CSS代码(css.css):
body{width:980px;margin:0 auto;font-family:"微软雅黑";color:#7d7d7d;}
img{border:0;}
h1,h2{text-align:center;position:relative;}
h1{color:#0092d3;}
h2{color:#53bde8;}
h3,h4,h5,h6{margin:0;}
ul,ol,li{margin:0;padding:0;text-align:left;vertical-align:top;}
li *{vertical-align:middle;}
a{color:#7d7d7d;}
a:hover{color:#000;}
.indent{margin-left:2em;}
.footer{text-align:right;font-size:12px;}
h1 img{vertical-align:middle;}
.code{margin-left:2em;background-color:#aaa;border-radius:5px;padding:5px;font-size:14px;color:#fff;}