全国省市县无刷新多级联动菜单

全国省市县无刷新多级联动菜单

<html>
<head>
<title>省市县关联菜单</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
body,select
{
font-size:9pt;
font-family:Verdana;
}
a
{
color:red;
text-decoration:none;
}
a:hover{
text-decoration:underline;
}
</style>
<SCRIPT LANGUAGE="JavaScript">
<!--
function Dsy()
{
this.Items = {};
}
Dsy.prototype.add = function(id,iArray)
{
this.Items[id] = iArray;
}
Dsy.prototype.Exists = function(id)
{
if(typeof(this.Items[id]) == "undefined") return false;
return true;
}

function change(v){
var str="0";
for(i=0;i<v;i++){ str+=("_"+(document.getElementById(s[i]).selectedIndex-1));};
var ss=document.getElementById(s[v]);
with(ss){
length = 0;
options[0]=new Option(opt0[v],opt0[v]);
if(v && document.getElementById(s[v-1]).selectedIndex>0 || !v)
{
if(dsy.Exists(str)){
ar = dsy.Items[str];
for(i=0;i<ar.length;i++)options[length]=new Option(ar[i],ar[i]);
if(v)options[1].selected = true;
}
}
if(++v<s.length){change(v);}
}
}

var dsy = new Dsy();

dsy.add ("0",["安徽","北京","福建","甘肃","广东","广西","贵州","海南","河北","河南","黑龙江","湖北","湖南", "吉林","江苏","江西","辽宁","内蒙古","宁夏","青海","山东","山西","陕西","上海","四川","天津","西藏"," 新疆","云南","浙江","重庆"]);

dsy.add("0_0",["安庆","蚌埠","巢湖","池州","滁州","阜阳","合肥","淮北","淮南","黄山","六安","马鞍山","宿州","铜陵","芜湖","宣城","亳州"]);
dsy.add("0_0_0",["安庆市","怀宁县","潜山县","宿松县","太湖县","桐城市","望江县","岳西县","枞阳县"]);
dsy.add("0_0_1",["蚌埠市","固镇县","怀远县","五河县"]);
dsy.add("0_0_2",["巢湖市","含山县","和县","庐江县","无为县"]);
dsy.add("0_0_3",["池州市","东至县","青阳县","石台县"]);
dsy.add("0_0_4",["滁州市","定远县","凤阳县","来安县","明光市","全椒县","天长市"]);
dsy.add("0_0_5",["阜南县","阜阳市","界首市","临泉县","太和县","颖上县"]);
dsy.add("0_0_6",["长丰县","肥东县","肥西县"]);
dsy.add("0_0_7",["淮北市","濉溪县"]);
dsy.add("0_0_8",["凤台县","淮南市"]);
dsy.add("0_0_9",["黄山市","祁门县","休宁县","歙县","黟县"]);
dsy.add("0_0_10",["霍邱县","霍山县","金寨县","六安市","寿县","舒城县"]);
dsy.add("0_0_11",["当涂县","马鞍山市"]);
dsy.add("0_0_12",["灵璧县","宿州市","萧县","泗县","砀山县"]);
dsy.add("0_0_13",["铜陵市","铜陵县"]);
dsy.add("0_0_14",["繁昌县","南陵县","芜湖市","芜湖县"]);
dsy.add("0_0_15",["广德县","绩溪县","郎溪县","宁国市","宣城市","泾县","旌德县"]);
dsy.add("0_0_16",["利辛县","蒙城县","涡阳县","亳州市"]);

dsy.add("0_1",["北京"]);
dsy.add("0_1_0",["北京市","密云县","延庆县"]);

dsy.add("0_2",["福州","龙岩","南平","宁德","莆田","泉州","三明","厦门","漳州"]);
dsy.add("0_2_0",["长乐市","福清市","福州市","连江县","罗源县","闽侯县","闽清县","平潭县","永泰县"]);
dsy.add("0_2_1",["长汀县","连城县","龙岩市","上杭县","武平县","永定县","漳平市"]);
dsy.add("0_2_2",["光泽县","建阳市","建瓯市","南平市","浦城县","邵武市","顺昌县","松溪县","武夷山市","政和县"]);
dsy.add("0_2_3",["福安市","福鼎市","古田县","宁德市","屏南县","寿宁县","霞浦县","周宁县","柘荣县"]);
dsy.add("0_2_4",["莆田市","仙游县"]);
dsy.add("0_2_5",["安溪县","德化县","惠安县","金门县","晋江市","南安市","泉州市","石狮市","永春县"]);
dsy.add("0_2_6",["大田县","建宁县","将乐县","明溪县","宁化县","清流县","三明市","沙县","泰宁县","永安市","尤溪县"]);
dsy.add("0_2_7",["厦门市"]);
dsy.add("0_2_8",["长泰县","东山县","华安县","龙海市","南靖县","平和县","云霄县","漳浦县","漳州市","诏安县"]);

dsy.add("0_3",["白银","定西","甘南藏族自治州","嘉峪关","金昌","酒泉","兰州","临夏回族自治州","陇南","平凉","庆阳","天水","武威","张掖"]);
dsy.add("0_3_0",["白银市","会宁县","景泰县","靖远县"]);
dsy.add("0_3_1",["定西县","临洮县","陇西县","通渭县","渭源县","漳县","岷县"]);
dsy.add("0_3_2",["迭部县","合作市","临潭县","碌曲县","玛曲县","夏河县","舟曲县","卓尼县"]);
dsy.add("0_3_3",["嘉峪关市"]);
dsy.add("0_3_4",["金昌市","永昌县"]);
dsy.add("0_3_5",["阿克塞哈萨克族自治县","安西县","敦煌市","金塔县","酒泉市","肃北蒙古族自治县","玉门市"]);
dsy.add("0_3_6",["皋兰县","兰州市","永登县","榆中县"]);
dsy.add("0_3_7",["东乡族自治县","广河县","和政县","积石山保安族东乡族撒拉族自治县","康乐县","临夏市","临夏县","永靖县"]);
dsy.add("0_3_8",["成县","徽县","康县","礼县","两当县","文县","武都县","西和县","宕昌县"]);
dsy.add("0_3_9",["崇信县","华亭县","静宁县","灵台县","平凉市","庄浪县","泾川县"]);
dsy.add("0_3_10",["合水县","华池县","环县","宁县","庆城县","庆阳市","镇原县","正宁县"]);
dsy.add("0_3_11",["甘谷县","秦安县","清水县","天水市","武山县","张家川回族自治县"]);
dsy.add("0_3_12",["古浪县","民勤县","天祝藏族自治县","武威市"]);
dsy.add("0_3_13",["高台县","临泽县","民乐县","山丹县","肃南裕固族自治县","张掖市"]);

dsy.add("0_4",["潮州","东莞","佛山","广州","河源","惠州","江门","揭阳","茂名","梅州","清远","汕头","汕尾","韶关","深圳","阳江","云浮","湛江","肇庆","中山","珠海"]);
dsy.add("0_4_0",["潮安县","潮州市","饶平县"]);
dsy.add("0_4_1",["东莞市"]);
dsy.add("0_4_2",["佛山市"]);
dsy.add("0_4_3",["从化市","广州市","增城市"]);
dsy.add("0_4_4",["东源县","和平县","河源市","连平县","龙川县","紫金县"]);
dsy.add("0_4_5",["博罗县","惠东县","惠阳市","惠州市","龙门县"]);
dsy.add("0_4_6",["恩平市","鹤山市","江门市","开平市","台山市"]);
dsy.add("0_4_7",["惠来县","揭东县","揭西县","揭阳市","普宁市"]);
dsy.add("0_4_8",["电白县","高州市","化州市","茂名市","信宜市"]);
dsy.add("0_4_9",["大埔县","丰顺县","蕉岭县","梅县","梅州市","平远县","五华县","兴宁市"]);
dsy.add("0_4_10",["佛冈县","连南瑶族自治县","连山壮族瑶族自治县","连州市","清新县","清远市","阳山县","英德市"]);
dsy.add("0_4_11",["潮阳市","澄海市","南澳县","汕头市"]);
dsy.add("0_4_12",["海丰县","陆丰市","陆河县","汕尾市"]);
dsy.add("0_4_13",["乐昌市","南雄市","曲江县","仁化县","乳源瑶族自治县","韶关市","始兴县","翁源县","新丰县"]);
dsy.add("0_4_14",["深圳市"]);
dsy.add("0_4_15",["阳春市","阳东县","阳江市","阳西县"]);
dsy.add("0_4_16",["罗定市","新兴县","郁南县","云安县","云浮市"]);
dsy.add("0_4_17",["雷州市","廉江市","遂溪县","吴川市","徐闻县","湛江市"]);
dsy.add("0_4_18",["德庆县","封开县","高要市","广宁县","怀集县","四会市","肇庆市"]);
dsy.add("0_4_19",["中山市"]);
dsy.add("0_4_20",["珠海市"]);

dsy.add("0_5",["百色","北海","崇左","防城港","桂林","贵港","河池","贺州","来宾","柳州","南宁","钦州","梧州","玉林"]);
dsy.add("0_5_0",["百色市","德保县","靖西县","乐业县","凌云县","隆林各族自治县","那坡县","平果县","田东县","田林县","田阳县","西林县"]);
dsy.add("0_5_1",["北海市","合浦县"]);
dsy.add("0_5_2",["崇左市","大新县","扶绥县","龙州县","宁明县","凭祥市","天等县"]);
dsy.add("0_5_3",["东兴市","防城港市","上思县"]);
dsy.add("0_5_4",["恭城瑶族自治县","灌阳县","桂林市","荔浦县","临桂县","灵川县","龙胜各族自治县","平乐县","全州县","兴安县","阳朔县","永福县","资源县"]);
dsy.add("0_5_5",["桂平市","贵港市","平南县"]);
dsy.add("0_5_6",["巴马瑶族自治县","大化瑶族自治县","东兰县","都安瑶族自治县","凤山县","河池市","环江毛南族自治县","罗城仡佬族自治县","南丹县","天峨县","宜州市"]);
dsy.add("0_5_7",["富川瑶族自治县","贺州市","昭平县","钟山县"]);
dsy.add("0_5_8",["合山市","金秀瑶族自治县","来宾市","武宣县","象州县","忻城县"]);
dsy.add("0_5_9",["柳城县","柳江县","柳州市","鹿寨县","融安县","融水苗族自治县","三江侗族自治县"]);
dsy.add("0_5_10",["宾阳县","横县","隆安县","马山县","南宁市","上林县","武鸣县","邕宁县"]);
dsy.add("0_5_11",["灵山县","浦北县","钦州市"]);
dsy.add("0_5_12",["苍梧县","蒙山县","藤县","梧州市","岑溪市"]);
dsy.add("0_5_13",["北流市","博白县","陆川县","容县","兴业县","玉林市"]);
dsy.add("0_6",["安顺","毕节","贵阳","六盘水","黔东南苗族侗族自治州","黔南布依族苗族自治州","黔西南布依族苗族自治州","铜仁","遵义"]);
dsy.add("0_6_0",["安顺市","关岭布依族苗族自治县","平坝县","普定县","镇宁布依族苗族自治县","紫云苗族布依族自治县"]);
dsy.add("0_6_1",["毕节市","大方县","赫章县","金沙县","纳雍县","黔西县","威宁彝族回族苗族自治县","织金县"]);
dsy.add("0_6_2",["贵阳市","开阳县","清镇市","息烽县","修文县"]);
dsy.add("0_6_3",["六盘水市","六枝特区","盘县","水城县"]);
dsy.add("0_6_4",["从江县","丹寨县","黄平县","剑河县","锦屏县","凯里市","雷山县","黎平县","麻江县","三穗县","施秉县","台江县","天柱县","镇远县","岑巩县","榕江县"]);
dsy.add("0_6_5",["长顺县","都匀市","独山县","福泉市","贵定县","惠水县","荔波县","龙里县","罗甸县","平塘县","三都水族自治县","瓮安县"]);
dsy.add("0_6_6",["安龙县","册亨县","普安县","晴隆县","望谟县","兴仁县","兴义市","贞丰县"]);
dsy.add("0_6_7",["德江县","江口县","石阡县","思南县","松桃苗族自治县","铜仁市","万山特区","沿河土家族自治县","印江土家族苗族自治县","玉屏侗族自治县"]);
dsy.add("0_6_8",["赤水市","道真仡佬族苗族自治县","凤冈县","仁怀市","绥阳县","桐梓县","务川仡佬族苗族自治县","习水县","余庆县","正安县","遵义市","遵义县","湄潭县"]);

dsy.add ("0_7",["白沙黎族自治县","保亭黎族苗族自治县","昌江黎族自治县","澄迈县","定安县","东方","海口","乐东黎族自治县", "临高县","陵水黎族自治县","琼海","琼中黎族苗族自治县","三亚","屯昌县","万宁","文昌","五指山","儋州"]);
dsy.add("0_7_0",["白沙黎族自治县"]);
dsy.add("0_7_1",["保亭黎族苗族自治县"]);
dsy.add("0_7_2",["昌江黎族自治县"]);
dsy.add("0_7_3",["澄迈县"]);
dsy.add("0_7_4",["定安县"]);
dsy.add("0_7_5",["东方市"]);
dsy.add("0_7_6",["海口市"]);
dsy.add("0_7_7",["乐东黎族自治县"]);
dsy.add("0_7_8",["临高县"]);
dsy.add("0_7_9",["陵水黎族自治县"]);
dsy.add("0_7_10",["琼海市"]);
dsy.add("0_7_11",["琼中黎族苗族自治县"]);
dsy.add("0_7_12",["三亚市"]);
dsy.add("0_7_13",["屯昌县"]);
dsy.add("0_7_14",["万宁市"]);
dsy.add("0_7_15",["文昌市"]);
dsy.add("0_7_16",["五指山市"]);
dsy.add("0_7_17",["儋州市"]);

dsy.add("0_8",["保定","沧州","承德","邯郸","衡水","廊坊","秦皇岛","石家庄","唐山","邢台","张家口"]);
dsy.add ("0_8_0",["安国市","安新县","保定市","博野县","定兴县","定州市","阜平县","高碑店市","高阳县","满城县"," 清苑县","曲阳县","容城县","顺平县","唐县","望都县","雄县","徐水县","易县","涞水县","涞源县","涿州市","蠡县 "]);
dsy.add("0_8_1",["泊头市","沧县","沧州市","东光县","海兴县","河间市","黄骅市","孟村回族自治县","南皮县","青县","任丘市","肃宁县","吴桥县","献县","盐山县"]);
dsy.add("0_8_2",["承德市","承德县","丰宁满族自治县","宽城满族自治县","隆化县","滦平县","平泉县","围场满族蒙古族自治县","兴隆县"]);
dsy.add("0_8_3",["成安县","磁县","大名县","肥乡县","馆陶县","广平县","邯郸市","邯郸县","鸡泽县","临漳县","邱县","曲周县","涉县","魏县","武安市","永年县"]);
dsy.add("0_8_4",["安平县","阜城县","故城县","衡水市","冀州市","景县","饶阳县","深州市","武强县","武邑县","枣强县"]);
dsy.add("0_8_5",["霸州市","大厂回族自治县","大城县","固安县","廊坊市","三河市","文安县","香河县","永清县"]);
dsy.add("0_8_6",["昌黎县","抚宁县","卢龙县","秦皇岛市","青龙满族自治县"]);
dsy.add("0_8_7",["高邑县","晋州市","井陉县","灵寿县","鹿泉市","平山县","深泽县","石家庄市","无极县","辛集市","新乐市","行唐县","元氏县","赞皇县","赵县","正定县","藁城市","栾城县"]);
dsy.add("0_8_8",["乐亭县","滦南县","滦县","迁安市","迁西县","唐海县","唐山市","玉田县","遵化市"]);
dsy.add("0_8_9",["柏乡县","广宗县","巨鹿县","临城县","临西县","隆尧县","南宫市","南和县","内丘县","宁晋县","平乡县","清河县","任县","沙河市","威县","新河县","邢台市","邢台县"]);
dsy.add("0_8_10",["赤城县","崇礼县","沽源县","怀安县","怀来县","康保县","尚义县","万全县","蔚县","宣化县","阳原县","张北县","张家口市","涿鹿县"]);

dsy.add("0_9",["安阳","鹤壁","济源","焦作","开封","洛阳","南阳","平顶山","三门峡","商丘","新乡","信阳","许昌","郑州","周口","驻马店","漯河","濮阳"]);
dsy.add("0_9_0",["安阳市","安阳县","滑县","林州市","内黄县","汤阴县"]);
dsy.add("0_9_1",["","鹤壁市","浚县","淇县"]);
dsy.add("0_9_2",["济源市"]);
dsy.add("0_9_3",["博爱县","焦作市","孟州市","沁阳市","温县","武陟县","修武县"]);
dsy.add("0_9_4",["开封市","开封县","兰考县","通许县","尉氏县","杞县"]);
dsy.add("0_9_5",["洛宁县","洛阳市","孟津县","汝阳县","新安县","伊川县","宜阳县","偃师市","嵩县","栾川县"]);
dsy.add("0_9_6",["邓州市","方城县","南阳市","南召县","内乡县","社旗县","唐河县","桐柏县","西峡县","新野县","镇平县","淅川县"]);
dsy.add("0_9_7",["宝丰县","鲁山县","平顶山市","汝州市","舞钢市","叶县","郏县"]);
dsy.add("0_9_8",["灵宝市","卢氏县","三门峡市","陕县","义马市","渑池县"]);
dsy.add("0_9_9",["民权县","宁陵县","商丘市","夏邑县","永城市","虞城县","柘城县","睢县"]);
dsy.add("0_9_10",["长垣县","封丘县","辉县市","获嘉县","卫辉市","新乡市","新乡县","延津县","原阳县"]);
dsy.add("0_9_11",["固始县","光山县","淮滨县","罗山县","商城县","息县","新县","信阳市","潢川县"]);
dsy.add("0_9_12",["长葛市","襄城县","许昌市","许昌县","禹州市","鄢陵县"]);
dsy.add("0_9_13",["登封市","巩义市","新密市","新郑市","郑州市","中牟县","荥阳市"]);
dsy.add("0_9_14",["郸城县","扶沟县","淮阳县","鹿邑县","商水县","沈丘县","太康县","西华县","项城市","周口市"]);
dsy.add("0_9_15",["泌阳县","平舆县","确山县","汝南县","上蔡县","遂平县","西平县","新蔡县","正阳县","驻马店市"]);
dsy.add("0_9_16",["临颍县","舞阳县","郾城县","漯河市"]);
dsy.add("0_9_17",["范县","南乐县","清丰县","台前县","濮阳市","濮阳县"]);

dsy.add("0_10",["大庆","大兴安岭","哈尔滨","鹤岗","黑河","鸡西","佳木斯","牡丹江","七台河","齐齐哈尔","双鸭山","绥化","伊春"]);
dsy.add("0_10_0",["大庆市","杜尔伯特蒙古族自治县","林甸县","肇源县","肇州县"]);
dsy.add("0_10_1",["呼玛县","漠河县","塔河县"]);
dsy.add("0_10_2",["阿城市","巴彦县","宾县","方正县","哈尔滨市","呼兰县","木兰县","尚志市","双城市","通河县","五常市","延寿县","依兰县"]);
dsy.add("0_10_3",["鹤岗市","萝北县","绥滨县"]);
dsy.add("0_10_4",["北安市","黑河市","嫩江县","孙吴县","五大连池市","逊克县"]);
dsy.add("0_10_5",["虎林市","鸡东县","鸡西市","密山市"]);
dsy.add("0_10_6",["抚远县","富锦市","佳木斯市","汤原县","同江市","桦川县","桦南县"]);
dsy.add("0_10_7",["东宁县","海林市","林口县","牡丹江市","穆棱市","宁安市","绥芬河市"]);
dsy.add("0_10_8",["勃利县","七台河市"]);
dsy.add("0_10_9",["拜泉县","富裕县","甘南县","克东县","克山县","龙江县","齐齐哈尔市","泰来县","依安县","讷河市"]);
dsy.add("0_10_10",["宝清县","集贤县","饶河县","双鸭山市","友谊县"]);
dsy.add("0_10_11",["安达市","海伦市","兰西县","明水县","青冈县","庆安县","绥化市","绥棱县","望奎县","肇东市"]);
dsy.add("0_10_12",["嘉荫县","铁力市","伊春市"]);

dsy.add("0_11",["鄂州","恩施土家族苗族自治州","黄冈","黄石","荆门","荆州","潜江","神农架林区","十堰","随州","天门","武汉","仙桃","咸宁","襄樊","孝感","宜昌"]);
dsy.add("0_11_0",["鄂州市"]);
dsy.add("0_11_1",["巴东县","恩施市","鹤峰县","建始县","来凤县","利川市","咸丰县","宣恩县"]);
dsy.add("0_11_2",["红安县","黄冈市","黄梅县","罗田县","麻城市","团风县","武穴市","英山县","蕲春县","浠水县"]);
dsy.add("0_11_3",["大冶市","黄石市","阳新县"]);
dsy.add("0_11_4",["荆门市","京山县","沙洋县","钟祥市"]);
dsy.add("0_11_5",["公安县","洪湖市","监利县","江陵县","荆州市","石首市","松滋市"]);
dsy.add("0_11_6",["潜江市"]);
dsy.add("0_11_7",["神农架林区"]);
dsy.add("0_11_8",["丹江口市","房县","十堰市","郧西县","郧县","竹山县","竹溪县"]);
dsy.add("0_11_9",["广水市","随州市"]);
dsy.add("0_11_10",["天门市"]);
dsy.add("0_11_11",["武汉市"]);
dsy.add("0_11_12",["仙桃市"]);
dsy.add("0_11_13",["赤壁市","崇阳县","嘉鱼县","通城县","通山县","咸宁市"]);
dsy.add("0_11_14",["保康县","谷城县","老河口市","南漳县","襄樊市","宜城市","枣阳市"]);
dsy.add("0_11_15",["安陆市","大悟县","汉川市","孝昌县","孝感市","应城市","云梦县"]);
dsy.add("0_11_16",["长阳土家族自治县","当阳市","五峰土家族自治县","兴山县","宜昌市","宜都市","远安县","枝江市","秭归县"]);

dsy.add("0_12",["常德","长沙","郴州","衡阳","怀化","娄底","邵阳","湘潭","湘西土家族苗族自治州","益阳","永州","岳阳","张家界","株洲"]);
dsy.add("0_12_0",["安乡县","常德市","汉寿县","津市市","临澧县","石门县","桃源县","澧县"]);
dsy.add("0_12_1",["长沙市","长沙县","宁乡县","望城县","浏阳市"]);
dsy.add("0_12_2",["安仁县","郴州市","桂东县","桂阳县","嘉禾县","临武县","汝城县","宜章县","永兴县","资兴市"]);
dsy.add("0_12_3",["常宁市","衡东县","衡南县","衡山县","衡阳市","衡阳县","祁东县","耒阳市"]);
dsy.add("0_12_4",["辰溪县","洪江市","怀化市","会同县","靖州苗族侗族自治县","麻阳苗族自治县","通道侗族自治县","新晃侗族自治县","中方县","芷江侗族自治县","沅陵县","溆浦县"]);
dsy.add("0_12_5",["冷水江市","涟源市","娄底市","双峰县","新化县"]);
dsy.add("0_12_6",["城步苗族自治县","洞口县","隆回县","邵东县","邵阳市","邵阳县","绥宁县","武冈市","新宁县","新邵县"]);
dsy.add("0_12_7",["韶山市","湘潭市","湘潭县","湘乡市"]);
dsy.add("0_12_8",["保靖县","凤凰县","古丈县","花垣县","吉首市","龙山县","永顺县","泸溪县"]);
dsy.add("0_12_9",["安化县","南县","桃江县","益阳市","沅江市"]);
dsy.add("0_12_10",["道县","东安县","江华瑶族自治县","江永县","蓝山县","宁远县","祁阳县","双牌县","新田县","永州市"]);
dsy.add("0_12_11",["华容县","临湘市","平江县","湘阴县","岳阳市","岳阳县","汨罗市"]);
dsy.add("0_12_12",["慈利县","桑植县","张家界市"]);
dsy.add("0_12_13",["茶陵县","炎陵县","株洲市","株洲县","攸县","醴陵市"]);

dsy.add("0_13",["白城","白山","长春","吉林","辽源","四平","松原","通化","延边朝鲜族自治州"]);
dsy.add("0_13_0",["白城市","大安市","通榆县","镇赉县","洮南市"]);
dsy.add("0_13_1",["白山市","长白朝鲜族自治县","抚松县","江源县","靖宇县","临江市"]);
dsy.add("0_13_2",["长春市","德惠市","九台市","农安县","榆树市"]);
dsy.add("0_13_3",["吉林市","磐石市","舒兰市","永吉县","桦甸市","蛟河市"]);
dsy.add("0_13_4",["东丰县","东辽县","辽源市"]);
dsy.add("0_13_5",["公主岭市","梨树县","双辽市","四平市","伊通满族自治县"]);
dsy.add("0_13_6",["长岭县","扶余县","乾安县","前郭尔罗斯蒙古族自治县","松原市"]);
dsy.add("0_13_7",["辉南县","集安市","柳河县","梅河口市","通化市","通化县"]);
dsy.add("0_13_8",["安图县","敦化市","和龙市","龙井市","图们市","汪清县","延吉市","珲春市"]);

dsy.add("0_14",["常州","淮安","连云港","南京","南通","苏州","宿迁","泰州","无锡","徐州","盐城","扬州","镇江"]);
dsy.add("0_14_0",["常州市","金坛市","溧阳市"]);
dsy.add("0_14_1",["洪泽县","淮安市","金湖县","涟水县","盱眙县"]);
dsy.add("0_14_2",["东海县","赣榆县","灌南县","灌云县","连云港市"]);
dsy.add("0_14_3",["高淳县","南京市","溧水县"]);
dsy.add("0_14_4",["海安县","海门市","南通市","启东市","如东县","如皋市","通州市"]);
dsy.add("0_14_5",["常熟市","昆山市","苏州市","太仓市","吴江市","张家港市"]);
dsy.add("0_14_6",["宿迁市","宿豫县","沭阳县","泗洪县","泗阳县"]);
dsy.add("0_14_7",["姜堰市","靖江市","泰兴市","泰州市","兴化市"]);
dsy.add("0_14_8",["江阴市","无锡市","宜兴市"]);
dsy.add("0_14_9",["丰县","沛县","铜山县","新沂市","徐州市","邳州市","睢宁县"]);
dsy.add("0_14_10",["滨海县","大丰市","东台市","阜宁县","建湖县","射阳县","响水县","盐城市","盐都县"]);
dsy.add("0_14_11",["宝应县","高邮市","江都市","扬州市","仪征市"]);
dsy.add("0_14_12",["丹阳市","句容市","扬中市","镇江市"]);

dsy.add("0_15",["抚州","赣州","吉安","景德镇","九江","南昌","萍乡","上饶","新余","宜春","鹰潭"]);
dsy.add("0_15_0",["崇仁县","东乡县","抚州市","广昌县","金溪县","乐安县","黎川县","南城县","南丰县","宜黄县","资溪县"]);
dsy.add("0_15_1",["安远县","崇义县","大余县","定南县","赣县","赣州市","会昌县","龙南县","南康市","宁都县","全南县","瑞金市","上犹县","石城县","信丰县","兴国县","寻乌县","于都县"]);
dsy.add("0_15_2",["安福县","吉安市","吉安县","吉水县","井冈山市","遂川县","泰和县","万安县","峡江县","新干县","永丰县","永新县"]);
dsy.add("0_15_3",["浮梁县","景德镇市","乐平市"]);
dsy.add("0_15_4",["德安县","都昌县","湖口县","九江市","九江县","彭泽县","瑞昌市","武宁县","星子县","修水县","永修县"]);
dsy.add("0_15_5",["安义县","进贤县","南昌市","南昌县","新建县"]);
dsy.add("0_15_6",["莲花县","芦溪县","萍乡市","上栗县"]);
dsy.add("0_15_7",["波阳县","德兴市","广丰县","横峰县","铅山县","上饶市","上饶县","万年县","余干县","玉山县","弋阳县","婺源县"]);
dsy.add("0_15_8",["分宜县","新余市"]);
dsy.add("0_15_9",["丰城市","奉新县","高安市","靖安县","上高县","铜鼓县","万载县","宜春市","宜丰县","樟树市"]);
dsy.add("0_15_10",["贵溪市","鹰潭市","余江县"]);

dsy.add("0_16",["鞍山","本溪","朝阳","大连","丹东","抚顺","阜新","葫芦岛","锦州","辽阳","盘锦","沈阳","铁岭","营口"]);
dsy.add("0_16_0",["鞍山市","海城市","台安县","岫岩满族自治县"]);
dsy.add("0_16_1",["本溪满族自治县","本溪市","桓仁满族自治县"]);
dsy.add("0_16_2",["北票市","朝阳市","朝阳县","建平县","喀喇沁左翼蒙古族自治县","凌源市"]);
dsy.add("0_16_3",["长海县","大连市","普兰店市","瓦房店市","庄河市"]);
dsy.add("0_16_4",["丹东市","东港市","凤城市","宽甸满族自治县"]);
dsy.add("0_16_5",["抚顺市","抚顺县","清原满族自治县","新宾满族自治县"]);
dsy.add("0_16_6",["阜新蒙古族自治县","阜新市","彰武县"]);
dsy.add("0_16_7",["葫芦岛市","建昌县","绥中县","兴城市"]);
dsy.add("0_16_8",["北宁市","黑山县","锦州市","凌海市","义县"]);
dsy.add("0_16_9",["灯塔市","辽阳市","辽阳县"]);
dsy.add("0_16_10",["大洼县","盘锦市","盘山县"]);
dsy.add("0_16_11",["法库县","康平县","辽中县","沈阳市","新民市"]);
dsy.add("0_16_12",["昌图县","调兵山市","开原市","铁岭市","铁岭县","西丰县"]);
dsy.add("0_16_13",["大石桥市","盖州市","营口市"]);

dsy.add("0_17",["阿拉善盟","巴彦淖尔盟","包头","赤峰","鄂尔多斯","呼和浩特","呼伦贝尔","通辽","乌海","乌兰察布盟","锡林郭勒盟","兴安盟"]);
dsy.add("0_17_0",["阿拉善右旗","阿拉善左旗","额济纳旗"]);
dsy.add("0_17_1",["杭锦后旗","临河市","乌拉特后旗","乌拉特前旗","乌拉特中旗","五原县","磴口县"]);
dsy.add("0_17_2",["包头市","达尔罕茂明安联合旗","固阳县","土默特右旗"]);
dsy.add("0_17_3",["阿鲁科尔沁旗","敖汉旗","巴林右旗","巴林左旗","赤峰市","喀喇沁旗","克什克腾旗","林西县","宁城县","翁牛特旗"]);
dsy.add("0_17_4",["达拉特旗","鄂尔多斯市","鄂托克旗","鄂托克前旗","杭锦旗","乌审旗","伊金霍洛旗","准格尔旗"]);
dsy.add("0_17_5",["和林格尔县","呼和浩特市","清水河县","土默特左旗","托克托县","武川县"]);
dsy.add("0_17_6",["阿荣旗","陈巴尔虎旗","额尔古纳市","鄂伦春自治旗","鄂温克族自治旗","根河市","呼伦贝尔市","满洲里市","莫力达瓦达斡尔族自治旗","新巴尔虎右旗","新巴尔虎左旗","牙克石市","扎兰屯市"]);
dsy.add("0_17_7",["霍林郭勒市","开鲁县","科尔沁左翼后旗","科尔沁左翼中旗","库伦旗","奈曼旗","通辽市","扎鲁特旗"]);
dsy.add("0_17_8",["乌海市"]);
dsy.add("0_17_9",["察哈尔右翼后旗","察哈尔右翼前旗","察哈尔右翼中旗","丰镇市","化德县","集宁市","凉城县","商都县","四子王旗","兴和县","卓资县"]);
dsy.add("0_17_10",["阿巴嘎旗","东乌珠穆沁旗","多伦县","二连浩特市","苏尼特右旗","苏尼特左旗","太仆寺旗","西乌珠穆沁旗","锡林浩特市","镶黄旗","正蓝旗","正镶白旗"]);
dsy.add("0_17_11",["阿尔山市","科尔沁右翼前旗","科尔沁右翼中旗","突泉县","乌兰浩特市","扎赉特旗"]);

dsy.add("0_18",["固原","石嘴山","吴忠","银川"]);
dsy.add("0_18_0",["固原市","海原县","隆德县","彭阳县","西吉县","泾源县"]);
dsy.add("0_18_1",["惠农县","平罗县","石嘴山市","陶乐县"]);
dsy.add("0_18_2",["青铜峡市","同心县","吴忠市","盐池县","中宁县","中卫县"]);
dsy.add("0_18_3",["贺兰县","灵武市","银川市","永宁县"]);

dsy.add("0_19",["果洛藏族自治州","海北藏族自治州","海东","海南藏族自治州","海西蒙古族藏族自治州","黄南藏族自治州","西宁","玉树藏族自治州"]);
dsy.add("0_19_0",["班玛县","达日县","甘德县","久治县","玛多县","玛沁县"]);
dsy.add("0_19_1",["刚察县","海晏县","门源回族自治县","祁连县"]);
dsy.add("0_19_2",["互助土族自治县","化隆回族自治县","乐都县","民和回族土族自治县","平安县","循化撒拉族自治县"]);
dsy.add("0_19_3",["共和县","贵德县","贵南县","同德县","兴海县"]);
dsy.add("0_19_4",["德令哈市","都兰县","格尔木市","天峻县","乌兰县"]);
dsy.add("0_19_5",["河南蒙古族自治县","尖扎县","同仁县","泽库县"]);
dsy.add("0_19_6",["大通回族土族自治县","西宁市","湟源县","湟中县"]);
dsy.add("0_19_7",["称多县","囊谦县","曲麻莱县","玉树县","杂多县","治多县"]);

dsy.add("0_20",["滨州","德州","东营","菏泽","济南","济宁","莱芜","聊城","临沂","青岛","日照","泰安","威海","潍坊","烟台","枣庄","淄博"]);
dsy.add("0_20_0",["滨州市","博兴县","惠民县","无棣县","阳信县","沾化县","邹平县"]);
dsy.add("0_20_1",["德州市","乐陵市","临邑县","陵县","宁津县","平原县","齐河县","庆云县","武城县","夏津县","禹城市"]);
dsy.add("0_20_2",["东营市","广饶县","垦利县","利津县"]);
dsy.add("0_20_3",["曹县","成武县","单县","定陶县","东明县","菏泽市","巨野县","郓城县","鄄城县"]);
dsy.add("0_20_4",["济南市","济阳县","平阴县","商河县","章丘市"]);
dsy.add("0_20_5",["济宁市","嘉祥县","金乡县","梁山县","曲阜市","微山县","鱼台县","邹城市","兖州市","汶上县","泗水县"]);
dsy.add("0_20_6",["莱芜市"]);
dsy.add("0_20_7",["东阿县","高唐县","冠县","聊城市","临清市","阳谷县","茌平县","莘县"]);
dsy.add("0_20_8",["苍山县","费县","临沂市","临沭县","蒙阴县","平邑县","沂南县","沂水县","郯城县","莒南县"]);
dsy.add("0_20_9",["即墨市","胶南市","胶州市","莱西市","平度市","青岛市"]);
dsy.add("0_20_10",["日照市","五莲县","莒县"]);
dsy.add("0_20_11",["东平县","肥城市","宁阳县","泰安市","新泰市"]);
dsy.add("0_20_12",["荣成市","乳山市","威海市","文登市"]);
dsy.add("0_20_13",["安丘市","昌乐县","昌邑市","高密市","临朐县","青州市","寿光市","潍坊市","诸城市"]);
dsy.add("0_20_14",["长岛县","海阳市","莱阳市","莱州市","龙口市","蓬莱市","栖霞市","烟台市","招远市"]);
dsy.add("0_20_15",["枣庄市","滕州市"]);
dsy.add("0_20_16",["高青县","桓台县","沂源县","淄博市"]);

dsy.add("0_21",["长治","大同","晋城","晋中","临汾","吕梁","朔州","太原","忻州","阳泉","运城"]);
dsy.add("0_21_0",["长治市","长治县","长子县","壶关县","黎城县","潞城市","平顺县","沁县","沁源县","屯留县","武乡县","襄垣县"]);
dsy.add("0_21_1",["大同市","大同县","广灵县","浑源县","灵丘县","天镇县","阳高县","左云县"]);
dsy.add("0_21_2",["高平市","晋城市","陵川县","沁水县","阳城县","泽州县"]);
dsy.add("0_21_3",["和顺县","介休市","晋中市","灵石县","平遥县","祁县","寿阳县","太谷县","昔阳县","榆社县","左权县"]);
dsy.add("0_21_4",["安泽县","大宁县","汾西县","浮山县","古县","洪洞县","侯马市","霍州市","吉县","临汾市","蒲县","曲沃县","襄汾县","乡宁县","翼城县","永和县","隰县"]);
dsy.add("0_21_5",["方山县","汾阳市","交城县","交口县","离石市","临县","柳林县","石楼县","文水县","孝义市","兴县","中阳县","岚县"]);
dsy.add("0_21_6",["怀仁县","山阴县","朔州市","应县","右玉县"]);
dsy.add("0_21_7",["古交市","娄烦县","清徐县","太原市","阳曲县"]);
dsy.add("0_21_8",["保德县","代县","定襄县","繁峙县","河曲县","静乐县","宁武县","偏关县","神池县","五台县","五寨县","忻州市","原平市","岢岚县"]);
dsy.add("0_21_9",["平定县","阳泉市","盂县"]);
dsy.add("0_21_10",["河津市","临猗县","平陆县","万荣县","闻喜县","夏县","新绛县","永济市","垣曲县","运城市","芮城县","绛县","稷山县"]);

dsy.add("0_22",["安康","宝鸡","汉中","商洛","铜川","渭南","西安","咸阳","延安","榆林"]);
dsy.add("0_22_0",["安康市","白河县","汉阴县","宁陕县","平利县","石泉县","旬阳县","镇坪县","紫阳县","岚皋县"]);
dsy.add("0_22_1",["宝鸡市","宝鸡县","凤县","凤翔县","扶风县","陇县","眉县","千阳县","太白县","岐山县","麟游县"]);
dsy.add("0_22_2",["城固县","佛坪县","汉中市","留坝县","略阳县","勉县","南郑县","宁强县","西乡县","洋县","镇巴县"]);
dsy.add("0_22_3",["丹凤县","洛南县","山阳县","商洛市","商南县","镇安县","柞水县"]);
dsy.add("0_22_4",["铜川市","宜君县"]);
dsy.add("0_22_5",["白水县","澄城县","大荔县","富平县","韩城市","合阳县","华县","华阴市","蒲城县","渭南市","潼关县"]);
dsy.add("0_22_6",["高陵县","户县","蓝田县","西安市","周至县"]);
dsy.add("0_22_7",["彬县","长武县","淳化县","礼泉县","乾县","三原县","武功县","咸阳市","兴平市","旬邑县","永寿县","泾阳县"]);
dsy.add("0_22_8",["安塞县","富县","甘泉县","黄陵县","黄龙县","洛川县","吴旗县","延安市","延长县","延川县","宜川县","志丹县","子长县"]);
dsy.add("0_22_9",["定边县","府谷县","横山县","佳县","靖边县","米脂县","清涧县","神木县","绥德县","吴堡县","榆林市","子洲县"]);

dsy.add("0_23",["上海"]);
dsy.add("0_23_0",["","崇明县","上海市"]);

dsy.add ("0_24",["阿坝藏族羌族自治州","巴中","成都","达州","德阳","甘孜藏族自治州","广安","广元","乐山","凉山彝族自 治州","眉山","绵阳","南充","内江","攀枝花","遂宁","雅安","宜宾","资阳","自贡","泸州"]);
dsy.add("0_24_0",["阿坝县","黑水县","红原县","金川县","九寨沟县","理县","马尔康县","茂县","壤塘县","若尔盖县","松潘县","小金县","汶川县"]);
dsy.add("0_24_1",["巴中市","南江县","平昌县","通江县"]);
dsy.add("0_24_2",["成都市","崇州市","大邑县","都江堰市","金堂县","彭州市","蒲江县","双流县","新津县","邛崃市","郫县"]);
dsy.add("0_24_3",["达县","达州市","大竹县","开江县","渠县","万源市","宣汉县"]);
dsy.add("0_24_4",["德阳市","广汉市","罗江县","绵竹市","什邡市","中江县"]);
dsy.add("0_24_5",["巴塘县","白玉县","丹巴县","稻城县","道孚县","德格县","得荣县","甘孜县","九龙县","康定县","理塘县","炉霍县","色达县","石渠县","乡城县","新龙县","雅江县","泸定县"]);
dsy.add("0_24_6",["广安市","华蓥市","邻水县","武胜县","岳池县"]);
dsy.add("0_24_7",["苍溪县","广元市","剑阁县","青川县","旺苍县"]);
dsy.add("0_24_8",["峨边彝族自治县","峨眉山市","夹江县","井研县","乐山市","马边彝族自治县","沐川县","犍为县"]);
dsy.add("0_24_9",["布拖县","德昌县","甘洛县","会东县","会理县","金阳县","雷波县","美姑县","冕宁县","木里藏族自治县","宁南县","普格县","西昌市","喜德县","盐源县","越西县","昭觉县"]);
dsy.add("0_24_10",["丹棱县","洪雅县","眉山市","彭山县","青神县","仁寿县"]);
dsy.add("0_24_11",["安县","北川县","江油市","绵阳市","平武县","三台县","盐亭县","梓潼县"]);
dsy.add("0_24_12",["南部县","南充市","蓬安县","西充县","仪陇县","营山县","阆中市"]);
dsy.add("0_24_13",["隆昌县","内江市","威远县","资中县"]);
dsy.add("0_24_14",["米易县","攀枝花市","盐边县"]);
dsy.add("0_24_15",["大英县","蓬溪县","射洪县","遂宁市"]);
dsy.add("0_24_16",["宝兴县","汉源县","芦山县","名山县","石棉县","天全县","雅安市","荥经县"]);
dsy.add("0_24_17",["长宁县","高县","江安县","南溪县","屏山县","兴文县","宜宾市","宜宾县","珙县","筠连县"]);
dsy.add("0_24_18",["安岳县","简阳市","乐至县","资阳市"]);
dsy.add("0_24_19",["富顺县","荣县","自贡市"]);
dsy.add("0_24_20",["古蔺县","合江县","叙永县","泸县","泸州市"]);

dsy.add("0_25",["天津"]);
dsy.add("0_25_0",["","蓟县","静海县","宁河县","天津市"]);

dsy.add("0_26",["阿里","昌都","拉萨","林芝","那曲","日喀则","山南"]);
dsy.add("0_26_0",["措勤县","噶尔县","改则县","革吉县","普兰县","日土县","札达县"]);
dsy.add("0_26_1",["八宿县","边坝县","察雅县","昌都县","丁青县","贡觉县","江达县","类乌齐县","洛隆县","芒康县","左贡县"]);
dsy.add("0_26_2",["达孜县","当雄县","堆龙德庆县","拉萨市","林周县","墨竹工卡县","尼木县","曲水县"]);
dsy.add("0_26_3",["波密县","察隅县","工布江达县","朗县","林芝县","米林县","墨脱县"]);
dsy.add("0_26_4",["安多县","巴青县","班戈县","比如县","嘉黎县","那曲县","尼玛县","聂荣县","申扎县","索县"]);
dsy.add ("0_26_5",["昂仁县","白朗县","定结县","定日县","岗巴县","吉隆县","江孜县","康马县","拉孜县","南木林县", "聂拉木县","仁布县","日喀则市","萨嘎县","萨迦县","谢通门县","亚东县","仲巴县"]);
dsy.add("0_26_6",["措美县","错那县","贡嘎县","加查县","浪卡子县","隆子县","洛扎县","乃东县","琼结县","曲松县","桑日县","扎囊县"]);

dsy.add ("0_27",["阿克苏","阿拉尔","巴音郭楞蒙古自治州","博尔塔拉蒙古自治州","昌吉回族自治州","哈密","和田","喀什","克 拉玛依","克孜勒苏柯尔克孜自治州","石河子","图木舒克","吐鲁番","乌鲁木齐","五家渠","伊犁哈萨克自治州"]);
dsy.add("0_27_0",["阿克苏市","阿瓦提县","拜城县","柯坪县","库车县","沙雅县","温宿县","乌什县","新和县"]);
dsy.add("0_27_1",["阿拉尔市"]);
dsy.add("0_27_2",["博湖县","和静县","和硕县","库尔勒市","轮台县","且末县","若羌县","尉犁县","焉耆回族自治县"]);
dsy.add("0_27_3",["博乐市","精河县","温泉县"]);
dsy.add("0_27_4",["昌吉市","阜康市","呼图壁县","吉木萨尔县","玛纳斯县","米泉市","木垒哈萨克自治县","奇台县"]);
dsy.add("0_27_5",["巴里坤哈萨克自治县","哈密市","伊吾县"]);
dsy.add("0_27_6",["策勒县","和田市","和田县","洛浦县","民丰县","墨玉县","皮山县","于田县"]);
dsy.add("0_27_7",["巴楚县","喀什市","麦盖提县","莎车县","疏附县","疏勒县","塔什库尔干塔吉克自治县","叶城县","英吉沙县","岳普湖县","泽普县","伽师县"]);
dsy.add("0_27_8",["克拉玛依市"]);
dsy.add("0_27_9",["阿合奇县","阿克陶县","阿图什市","乌恰县"]);
dsy.add("0_27_10",["石河子市"]);
dsy.add("0_27_11",["图木舒克市"]);
dsy.add("0_27_12",["吐鲁番市","托克逊县","鄯善县"]);
dsy.add("0_27_13",["乌鲁木齐市","乌鲁木齐县"]);
dsy.add("0_27_14",["五家渠市"]);
dsy.add ("0_27_15",["阿勒泰市","布尔津县","察布查尔锡伯自治县","额敏县","福海县","富蕴县","巩留县","哈巴河县","和布 克赛尔蒙古自治县","霍城县","吉木乃县","奎屯市","尼勒克县","青河县","沙湾县","塔城市","特克斯县","托里县","乌苏市 ","新源县","伊宁市","伊宁县","裕民县","昭苏县"]);

dsy.add("0_28",["保山","楚雄彝族自治州", "大理白族自治州","德宏傣族景颇族自治州","迪庆藏族自治州","红河哈尼族彝族自治州","昆明","丽江","临沧","怒江傈傈族自治州", "曲靖","思茅","文山壮族苗族自治州","西双版纳傣族自治州","玉溪","昭通"]);
dsy.add("0_28_0",["保山市","昌宁县","龙陵县","施甸县","腾冲县"]);
dsy.add("0_28_1",["楚雄市","大姚县","禄丰县","牟定县","南华县","双柏县","武定县","姚安县","永仁县","元谋县"]);
dsy.add("0_28_2",["宾川县","大理市","洱源县","鹤庆县","剑川县","弥渡县","南涧彝族自治县","巍山彝族回族自治县","祥云县","漾濞彝族自治县","永平县","云龙县"]);
dsy.add("0_28_3",["梁河县","陇川县","潞西市","瑞丽市","盈江县"]);
dsy.add("0_28_4",["德钦县","维西傈僳族自治县","香格里拉县"]);
dsy.add("0_28_5",["个旧市","河口瑶族自治县","红河县","建水县","金平苗族瑶族傣族自治县","开远市","绿春县","蒙自县","弥勒县","屏边苗族自治县","石屏县","元阳县","泸西县"]);
dsy.add("0_28_6",["安宁市","呈贡县","富民县","晋宁县","昆明市","禄劝彝族苗族自治县","石林彝族自治县","寻甸回族自治县","宜良县","嵩明县"]);
dsy.add("0_28_7",["华坪县","丽江市","宁蒗彝族自治县","永胜县","玉龙纳西族自治县"]);
dsy.add("0_28_8",["沧源佤族自治县","凤庆县","耿马傣族佤族治县","临沧县","双江拉祜族佤族布朗族傣族自治县","永德县","云县","镇康县"]);
dsy.add("0_28_9",["福贡县","贡山独龙族怒族自治县","兰坪白族普米族自治县","泸水县"]);
dsy.add("0_28_10",["富源县","会泽县","陆良县","罗平县","马龙县","曲靖市","师宗县","宣威市","沾益县"]);
dsy.add ("0_28_11",["江城哈尼族彝族自治县","景东彝族自治县","景谷彝族傣族自治县","澜沧拉祜族自治县","孟连傣族拉祜族佤族自治县 ","墨江哈尼族自治县","普洱哈尼族彝族自治县","思茅市","西盟佤族自治县","镇沅彝族哈尼族拉祜族自治县"]);
dsy.add("0_28_12",["富宁县","广南县","麻栗坡县","马关县","丘北县","文山县","西畴县","砚山县"]);
dsy.add("0_28_13",["景洪市","勐海县","勐腊县"]);
dsy.add("0_28_14",["澄江县","峨山彝族自治县","华宁县","江川县","通海县","新平彝族傣族自治县","易门县","玉溪市","元江哈尼族彝族傣族自治县"]);
dsy.add("0_28_15",["大关县","鲁甸县","巧家县","水富县","绥江县","威信县","盐津县","彝良县","永善县","昭通市","镇雄县"]);

dsy.add("0_29",["杭州","湖州","嘉兴","金华","丽水","宁波","绍兴","台州","温州","舟山","衢州"]);
dsy.add("0_29_0",["淳安县","富阳市","杭州市","建德市","临安市","桐庐县"]);
dsy.add("0_29_1",["安吉县","长兴县","德清县","湖州市"]);
dsy.add("0_29_2",["海宁市","海盐县","嘉善县","嘉兴市","平湖市","桐乡市"]);
dsy.add("0_29_3",["东阳市","金华市","兰溪市","磐安县","浦江县","武义县","义乌市","永康市"]);
dsy.add("0_29_4",["景宁畲族自治县","丽水市","龙泉市","青田县","庆元县","松阳县","遂昌县","云和县","缙云县"]);
dsy.add("0_29_5",["慈溪市","奉化市","宁波市","宁海县","象山县","余姚市"]);
dsy.add("0_29_6",["上虞市","绍兴市","绍兴县","新昌县","诸暨市","嵊州市"]);
dsy.add("0_29_7",["临海市","三门县","台州市","天台县","温岭市","仙居县","玉环县"]);
dsy.add("0_29_8",["苍南县","洞头县","乐清市","平阳县","瑞安市","泰顺县","温州市","文成县","永嘉县"]);
dsy.add("0_29_9",["舟山市","岱山县","嵊泗县"]);
dsy.add("0_29_10",["常山县","江山市","开化县","龙游县","衢州市"]);

dsy.add("0_30",["重庆"]);
dsy.add ("0_30_0",["城口县","大足县","垫江县","丰都县","奉节县","合川市","江津市","开县","梁平县","南川市","彭 水苗族土家族自治县","荣昌县","石柱土家族自治县","铜梁县","巫山县","巫溪县","武隆县","秀山土家族苗族自治县","永川市"," 酉阳土家族苗族自治县","云阳县","忠县","重庆市","潼南县","璧山县","綦江县"]);
//-->
</SCRIPT>
<SCRIPT LANGUAGE = JavaScript>
<!--
//** Power by Fason(2004-3-11)
//** Email:fason_pfx@hotmail.com

var s=["s1","s2","s3"];
var opt0 = ["省份","地级市","市、县级市、县"];
function setup()
{
for(i=0;i<s.length-1;i++)
document.getElementById(s[i]).onchange=new Function("change("+(i+1)+")");
change(0);
}
//-->
</SCRIPT>
</head>
<body bgcolor="#E0E0E0" onload="setup()">
多级关联菜单:
<form name="frm">
<select id="s1"><option>省份</option></select>
<select id="s2"><option>地级市</option></select>
<select id="s3"><option>市、县级市、县</option></select>
</form>
</body>
</html>

Posted: 2006年7月31日 10:29 by admin | 0 Comments
Filed under: 联动菜单
关于SELECT的无限联动菜单

index.asp
程序代码: 
<html>
<head>
<title></title>
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<style type="text/css"><!--
  FONT{font-size:12px}
  TD{font-size:12px}
  A{color:#333399}
  A:hover{color:#FF6600}
--></style>
<script language="Javascript" type="text/Javascript"><!--
function funOnload(){
  document.all.list_file.src="jscript_city.asp?base=0&sele=0-&elem=Select01";
}

//pBase级数,以0基,
//pSele是<option 的value值
//pEle是下一级的表单名字
function chgSelect(pBase,pSele,pElem){
  //当改变了一个列表之后。清除以后的列表的值。
  for(i=parseInt(pElem.replace("Select",""));i<=5;i++){
    var tmp="000"+i;
    var pElem1=eval("document.Form1.Select"+tmp.substr(tmp.length-2));

    pElem1.length=1;
    pElem1.selectedIndex=0;
  }

  //JS用ASP得到数据库的数据来更新下级列表
  document.all.list_file.src="jscript_city.asp?base="+pBase+"&sele="+pSele+"&elem="+pElem;
}

//--></script>
<script id="list_file" language="Javascript" type="text/Javascript" src=""></script>
</head>

<body bgcolor="#FFFFFF" leftmargin="0" topmargin="2" text="#333333" onload="funOnload();">
<form name="Form1">
<select name="Select01" onchange="chgSelect(1,this.options[this.selectedIndex].value,'Select02')">
  <option value="">省...</option>
</select>
<select name="Select02" onchange="chgSelect(2,this.options[this.selectedIndex].value,'Select03')">
  <option value="">市...</option>
</select>
<select name="Select03" onchange="chgSelect(3,this.options[this.selectedIndex].value,'Select04')">
  <option value="">县...</option>
</select>
<select name="Select04" onchange="chgSelect(4,this.options[this.selectedIndex].value,'Select05')">
  <option value="">乡...</option>
</select>
<select name="Select05">
  <option value="">村...</option>
</select>
</form>
</body></html> 


'jscript_city.asp
程序代码: 
<%
' varBase 下拉菜单等级
' varSele 所选择下拉菜单项的数据库ID
' varElem 下一级的表单名称

varBase=Request.QueryString("base")
varSele=Left(Request.QueryString("sele"),InStr(Request.QueryString("sele"),"-")-1)
varElem=Request.QueryString("elem")

varDistName=""
varAutoID=""

Set conDB=Server.CreateObject("ADODB.CONNECTION")
conDB.Open "Driver={Microsoft Access Driver (*.mdb)};DBQ="&Server.Mappath("db1.mdb")

sqlCommand="select * from table1 where filed1="&varBase&" and filed2="&varSele
Set rsRecord=conDB.Execute(sqlCommand)

While Not rsRecord.eof
  varDistName=varDistName&chr(34)&rsRecord("filed3")&chr(34)
  varAutoID=varAutoID&chr(34)&rsRecord("id")&chr(34)

  rsRecord.movenext
  If Not rsRecord.Eof Then
    varDistName=varDistName&","
    varAutoID=varAutoID&","
  End If
Wend

Response.Write("var varDistName=new Array("&varDistName&")"&vbcrlf)
Response.Write("var varAutoID=new Array("&varAutoID&")"&vbcrlf)

Response.Write("var varElem=eval("&chr(34)&"document.Form1."&varElem&chr(34)&")"&vbcrlf)

Response.Write("varElem.length=varDistName.length+1;"&vbcrlf)

Response.Write("for(var i=0;i<varDistName.length;i++){"&vbcrlf)
Response.Write("    varElem.options[i+1].text=varDistName;"&vbcrlf)
Response.Write("    varElem.options[i+1].value=varAutoID+'-'+varDistName;"&vbcrlf)
Response.Write("}"&vbcrlf)

Response.Write("varElem.selectedIndex=0;"&vbcrlf)

%> 

db1.mdb
'-------------------------------------------------
福建 厦门 思明 黄厝 曾厝桉村
福建 泉州 丰泽 西湖 水头村

如上面的五级转成数据库为:
'-------------------------------
id    filed1    filed2    filed3
1    0        0        福建
2    1        1        厦门
3    1        1        泉州
4    2        2        思明
5    3        4        黄厝
6    4        5        曾厝桉村
7    2        3        丰泽
8    3        7        西湖
9    4        8        水头村
'-------------------------------------------------
数据库说明:
id 自动编号
filed1 下拉菜单列表的等级(看级数。可以设置它的精度。是数字类型)
filed2 上一级的id号(用长整型吧)
filed3 这个就不用说了吧(文件。长度自己看情况)

本程序在IIS4+WIN2000P+ACCESS2000下通过。

来源:http://www.it055.com/it055_infos/net_programs/asp/1590_page1.htm

Posted: 2006年7月31日 9:40 by admin | 0 Comments
Filed under: 联动菜单
JavaScript对正则exec的扩展
<script>
<!--
re=/\[((\w|\.)+)\]/g
str="abd[my.name]xx[pop]d[width]f"
m=str.match(re)
alert(m) //结果:w12,w32,w45,w62 即:匹配的字符串(注:非括号的)
//re.lastIndex=0 //体现lastIndex特性 让正则从新开始查找
//-----------------------------------------
RegExp.prototype._exec=function(str){var arr=[];if(this.global){this.lastIndex=0;while((a=this.exec(str))!=null){arr.push(a[1])}return arr;}else{return arr.concat(this.exec(str))}}
m=re._exec(str)
alert(m) //结果:12,32,45,22
//默认 match对应的是 Match(匹配到的字符串)不是Paren 而exec对应的是Paren(括号的模数组)
//-->
</script>
JavaScript异常处理

异常处理概述
在 代码的运行过程中,错误是不可避免的,总的来说,错误发生于两种情况:一是程序内部的逻辑或者语法错误,二是运行环境或者用户输入中不可预知的数据造成的 错误。对于前者,就称之为错误(error),可以通过调试程序来解决;而后一种则更多的称之为异常(exception),顾名思义,就是超出常规,没 有按程序设计的意愿来输入数据。当然,异常还会有许多种类型。
所以说,异常并不等价于错误,相反,有时还会利用异常来解决一些问题。JavaScript可以捕获一个异常并进行相应的处理,从而避免了浏览器向用户报错。

使用try-catch-finally处理异常
用户可以使用该结构处理可能发生异常的代码,如果发生异常,则由catch捕获并进行处理,其语法如下:
try{
       //要执行的代码
}
catch(e){
       //处理异常的代码
}
finally{
       //无论异常发生与否,都会执行的代码
}
通过异常处理,可以避免程序停止运行,从而具有了一定的自我修复能力。
在Ajax开发中,利用异常处理的一个典型应用就是创建XMLHttpRequest对象,不同浏览器创建它的方式是不一样的,为了使代码能够跨浏览器运行,就可以利用异常,一种方法不行,再用另一种方法,直到不发生异常为止,例如:
<script language="JavaScript" type="text/javascript">
<!--
var xmlhttp;
try{
      //尝试用IE浏览器的方式创建XMLHttpRequest对象
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
      try{
           //尝试用非IE浏览器的方式常见XMLHttpRequest对象
           xmlhttp=new XMLHttpRequest();
      }catch(e){}
}
//-->
</script>
通过这种方式,就可以跨浏览器创建XMLHttpRequest对象。注意,即使不在catch块内进行处理,catch标识及其参数e也是必须写的,否则会产生语法错误,而finnally则不是必须的。
 
使用throw语句抛出异常
在JavaScript中有其内部的异常机制,在遇到非法操作时能自动抛出异常。实际的开发中,随着程序的复杂,需要能自己实现异常,这可以通过throw语句来实现:
throw value;
其 中value就是要抛出的异常变量,它可以是JavaScript中的任何一种类型。但在JavaScript内部的异常中,异常参数(即catch (e)中的e)是一个名为error的对象,可以通过new Error(message)来创建这个对象,异常的描述被作为error对象的一个属性message,可以由构造函数传入,也可以之后赋值。通过这个 异常描述message,可以让程序获取异常的详细信息,从而自动处理。
下面的程序计算两个数据的和,如果参数不是数字,则抛出异常,代码如下:
<script language="JavaScript" type="text/javascript">
<!--
//函数默认要求参数为数字
function sum(a,b){
      a=parseInt(a);
      b=parseInt(b);
      //如果a或b不能转换为数字则抛出一个异常对象
      if(isNaN(a) || isNaN(b)){
              throw new Error("arguments are not numbers");
      }
      return a+b;
}

try{
      //错误的调用
      var s=sum("c","d");
}catch(e){
      //显示异常的详细信息
      alert(e.message);
}
//-->
</script>
程序中使用字母作为参数传递给sum函数,是错误的,所以函数内抛出了一个异常对象,这个对象被catch语句获取,并使用alert语句显示了其详细信息。
注意:使用new Error(message)创建异常对象只是一种默认的习惯,也是内置异常的实现方式。这不是必需的,完全可以抛出任意数据类型的异常,例如一个整数,来作为异常的描述。只要在程序中抛出异常和捕获异常能匹配即可。

Error 对象除了message属性以外,还有一些其他的属性,这些属性因浏览器而异,例如:在IE浏览器中,error对象的属性包括name、number、 description、message;而在Firefox浏览器中,error对象的属性包括message、fileName、 lineNumber、stack、name。在实际的应用中如果要实现自己的异常,这些属性只要被赋值,都是可用的,其中Firefox浏览器还会自动 对stack属性赋值,用于显示异常出现的位置。
 

JavaScript使用Window对象
使用Window.open方法新建窗口
Window对象表示的是浏览器窗口,它有多种操作,其中一个重要的方法是open,表示新建一个窗口来打开指定页面。例如在a.html中执行以下语句:
window.open("b.html");
则新建一个窗口打开了b.html页面,这和在a.html页面中用一条链接打开页面的效果是一样的:
<a href="b.html" target="_blank">b</html>
但window.open对新建窗口的样式可以有更多的控制,例如:窗口大小、是否显示菜单栏、是否显示滚动条、是否显示地址栏等等。其完整的调用语法如下:
window.open(url,windowName,"name1=value1[,name2=value2,[…]]");
其中:url是要打开的页面地址;windowName表示新建窗口的名字,从而可以对其进行控制;最后是一个用字符串表示的参数列表。每一个参数都是名称和值对应的形式,用逗号隔开,其中可以使用的参数如下。
? height:表示新建窗口的高度;
? width:表示新建窗口的宽度;
? left:表示新建窗口到屏幕左边缘的距离;
? top:表示新建窗口到屏幕顶端的距离。
以 上属性的单位均为象素,例如对于800×600的分辨率,left=400则表示新窗口的左边缘处于屏幕的正中间。其余的属性主要是布尔型的,用yes或 者1表示开启,用no或者0表示关闭。如果是开启,则yes或者1可省略,例如:toolbar=1等价于toolbar=yes等价于toolbar, 下面分别介绍这些属性:
? directories:是否显示链接工具栏;
? location:是否显示地址栏;
? menubar:是否显示菜单栏;
? resizable:是否允许调整窗口大小;
? scrollbars:是否显示滚动条;
? status:是否显示状态栏;
? toolbar:是否显示工具栏。
例如,下面的代码将显示一个无菜单、无工具条、无滚动条的窗口:
window.open("test3.html","","height=200,width=300, toolbar=0,menubar=0,scrollbars=0");
 
使用定时器实现JavaScript的延期执行或重复执行
window对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和window.setInterval。其中前者可以使一段代码在指定时间后运行;而后者则可以使一段代码每过指定时间就运行一次。它们的原型如下:
window.setTimeout(expression,milliseconds);
window.setInterval(expression,milliseconds);
其 中,expression可以是用引号括起来的一段代码,也可以是一个函数名,到了指定的时间,系统便会自动调用该函数,当使用函数名作为调用句柄时,不 能带有任何参数;而使用字符串时,则可以在其中写入要传递的参数。两个方法的第二个参数是milliseconds,表示延时或者重复执行的毫秒数。下面 分别介绍两种方法。
 
1.window.setTimeout方法
该方法可以延时执行一个函数,例如:
<script language="JavaScript" type="text/javascript">
<!--
function hello(){
 alert("hello");
}
window.setTimeout(hello,5000);
//-->
</script>
这段代码将使得页面打开5秒钟后显示对话框“hello”。其中最后一句也可以写为:
window.setTimeout("hello()",5000);
读者可以体会它们的差别,在window.setInterval方法中也有这样的性质。
如果在延时期限到达之前取消延执行,可以使用window.clearTimeout(timeoutId)方法,该方法接收一个id,表示一个定时器。这个id是由setTimeout方法返回的,例如:
<script language="JavaScript" type="text/javascript">
<!--
function hello(){
      alert("hello");
}
var id=window.setTimeout(hello,5000);
document.onclick=function(){
     window.clearTimeout(id);
}
//-->
</script>
这样,如果要取消显示,只需单击页面任何一部分,就执行了window.clearTimeout方法,使得超时操作被取消。

2.window.setInterval方法
该 方法使得一个函数每隔固定时间被调用一次,是一个很常用的方法。如果想要取消定时执行,和clearTimeout方法类似,可以调用 window.clearInterval方法。clearInterval方法同样接收一个setInterval方法返回的值作为参数。例如:
//定义一个反复执行的调用
var id=window.setInterval("somefunction",10000);
//取消定时执行
window.clearInterval(id);
上 面的代码仅用于说明怎样取消一个定时执行。实际上在很多场合都需要用到setInterval方法,下面将设计一个秒表,来介绍setInterval函 数的用途:该秒表将包括两个按钮和一个用于显示时间的文本框。当单击开始按钮时开始计时,最小单位为0.01秒,此时再次单击按钮则停止计时,文本框显示 经过的时间。另外一个按钮用于将当前时间清零。其实现代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> New Document </title>
</head>
<body>
<form action="somepage.asp">
<input type="text" value="0" name="txt1"/>
<input type="button" value="开始" name="btnStart"/>
<input type="button" value="重置" name="btnReset"/>
</form>
</body>
</html>
<script language="JavaScript" type="text/javascript">
<!--
//获取表单中的表单域
var txt=document.forms[0].elements["txt1"];
var btnStart=document.forms[0].elements["btnStart"];
var btnReset=document.forms[0].elements["btnReset"]
//定义定时器的id
var id;
//每10毫秒该值增加1
var seed=0;

btnStart.onclick=function(){
      //根据按钮文本来判断当前操作
      if(this.value=="开始"){
              //使按钮文本变为停止
              this.value="停止";
              //使重置按钮不可用
              btnReset.disabled=true;
              //设置定时器,每0.01s跳一次
              id=window.setInterval(tip,10);
      }else{
              //使按钮文本变为开始
              this.value="开始";
              //使重置按钮可用
              btnReset.disabled=false;
              //取消定时
              window.clearInterval(id);
      }
}

//重置按钮
btnReset.onclick=function(){
     seed=0;
}
//让秒表跳一格
function tip(){
      seed++;
      txt.value=seed/100;
}
//-->
</script>
给定时器调用传递参数
无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,这就需要想方法解决。例如对于函数hello(_name),它用于针对用户名显示欢迎信息:
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name){
      alert("hello,"+_name);
}
这时,如果企图使用以下语句来使hello函数延迟3秒执行是不可行的:
window.setTimeout(hello(userName),3000);
这将使hello函数立即执行,并将返回值作为调用句柄传递给setTimeout函数,其结果并不是程序需要的。而使用字符串形式可以达到想要的结果:
window.setTimeout("hello(userName)",3000);
这里的字符串是一段JavaScript代码,其中的userName表示的是变量。但这种写法不够直观,而且有些场合必须使用函数名,下面用一个小技巧来实现带参数函数的调用:
<script language="JavaScript" type="text/javascript">
<!--
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name){
       alert("hello,"+_name);
}
//创建一个函数,用于返回一个无参数函数
function _hello(_name){
       return function(){
             hello(_name);
       }
}
window.setTimeout(_hello(userName),3000);
//-->
</script>
这 里定义了一个函数_hello,用于接收一个参数,并返回一个不带参数的函数,在这个函数内部使用了外部函数的参数,从而对其调用,不需要使用参数。在 window.setTimeout函数中,使用_hello(userName)来返回一个不带参数的函数句柄,从而实现了参数传递的功能。

使用status和defaultStatus属性改变状态栏信息
status和defaultStatus是window对象的属性,用于设置状态栏信息,语法为:
window.status="message";
window.defaultStatus="message";

其中status属性就是用于设置状态栏显示的文本。而defaultStatus表示默认的状态栏信息,例如默认情况下IE浏览器会显示“完毕”,而Firefox浏览器则显示“完成”。可以通过defaultStatus来改变这一信息。
使用alert、prompt和confirm语句与用户进行交互
这三个语句都是弹出一个对话框,来处理用户输入。它们都是window对象的一个方法,在实际使用时,常常省略window,而直接写成alert("hello")类似的形式。下面分别介绍:
1.alert语句
该语句的原型是:
window.alert(message);
alert接收一个参数,该参数将转换为字符串直接显示在对话框上,例如:
alert("hello,ajax");
2.prompt语句
该语句的原型是:
window.prompt(message,defaultValue);
prompt用于让用户输入一个值,其中message表示提示信息,defaultValue表示显示于文本框的初始值;函数返回用户的输入。对话框包括【确定】和【取消】两个按钮,用户单击【确定】按钮则返回文本框中的内容,单击【取消】则返回null。例如:
var userName=window.prompt("请输入您的姓名:","");
alert("hello,"+userName);
其中prompt提示用户输入其姓名,使用userName变量获取用户输入,并显示欢迎信息。

3.confirm语句
该语句的原型是:
window.confirm(message);
其作用是显示一条信息让用户确认,弹出的对话框包括【确定】和【取消】两个按钮,如果用户单击【确定】,则confirm函数返回true,否则返回false。例如下面的语句:
if(confirm("确定删除该记录吗?")){
       //删除记录的操作
}else{
       //不删除记录
}

JavaScript仿Windows关机效果

基本原理分析

Windows关机效果分析
使用Windows系统的用户在关机的时候,出现的界面只允许用户选择关机、注销或取消动作,而桌面上的程序都不能使用,并且屏幕呈现灰色状态。

本例将仿照这种高亮显示的效果在网页上实现.

在网页上运用这种关机效果有什么好处呢?首先,由于单击某一链接后,将用户此时不可用的操作隐藏在后台,将可用的操作放在屏幕最上层,并高亮显示,可以避免用户的误操作。其次,将信息高亮显示,也可以提醒用户应该注意的事项。 
网页中实现关机效果分析
在网页中实现这种效果的原理很简单。创建两个图层,一个为遮盖层,覆盖整个页面,并且显示为灰色;另一个图层作为高亮显示的部分,在遮盖层的上方,这可通过设置图层的z-index属性来设置。当取消关机效果后,只需将这两个图层元素在页面中删除即可。
以下代码实现显示关机效果。
<html>
<head>
<title>AJAX LightBox Sample</title>
<style type="text/css">
#lightbox {/*该层为高亮显示层*/
       BORDER-RIGHT: #fff 1px solid;
       BORDER-TOP: #fff 1px solid;
       DISPLAY: block; 
       Z-INDEX: 9999; /*设置该层在网页的最上端,设置足够大*/
       BACKGROUND: #fdfce9; /*设置背景色*/
       LEFT: 50%; 
       MARGIN: -220px 0px 0px -250px; 
       BORDER-LEFT: #fff 1px solid; 
       WIDTH: 500px; 
       BORDER-BOTTOM: #fff 1px solid; 
       POSITION: absolute; 
       TOP: 50%; 
       HEIGHT: 400px; 
       TEXT-ALIGN: left
}
#overlay {/*该层为覆盖层*/
      DISPLAY: block;
      Z-INDEX: 9998; /*设置高亮层的下方*/
      FILTER: alpha(opacity=80); /*设置成透明*/
      LEFT: 0px; 
      WIDTH: 100%; 
      POSITION: absolute; 
      TOP: 0px; 
      HEIGHT: 100%; 
      BACKGROUND-COLOR: #000; 
      moz-opacity: 0.8; 
      opacity: .80
}
</style>
</head>
<body>
<!--该层为覆盖层 -->
<div id="overlay"></div>
<!--该层为高亮显示层 -->
<div id="lightbox"></div>
</body>
</html>
需要注意的是,在IE浏览器中如果有<select>标记,则该标记不能被覆盖层覆盖,但在其他浏览器中则可以覆盖。

在使用IE浏览器时,要先将网页中的<select>元素隐藏起来。如以下代码可以用于隐藏页面所有的<select>元素。
selects = document.getElementsByTagName('select');
for(i = 0; i < selects.length; i++) {
       selects[i].style.visibility = visibility;
}
 


代码实现


客户端代码
客户端的页面上有两个链接,用户单击链接后,向服务器端发送请求,并将返回信息显示到高亮层上。客户端的网页文件代码如下所示:
<html>
<head>
<title>AJAX LightBox</title>
<!-- 本例使用的css样式表文件-->
<LINK href="lightbox.css" type=text/css rel=stylesheet>
<!--prototype类文件-->
<script type="text/javascript" src="js/prototype.js" ></script>
<!--本例使用的javascript代码-->
<script type="text/javascript" src="lightbox.js" ></script>
</head>
<body>
<DIV id=container>
<UL>
  <LI><A class=lbOn href="getInfo.jsp?id=one">One</A> 
  </LI>
  <LI><A class=lbOn href="getInfo.jsp?id=two">Two</A> 
  </LI>
</UL>
</div>
</body>
</html>
 

另外,还需要设置该页面所使用CSS样式。lightbox.css样式表文件代码如下所示:
#lightbox {
      BORDER-RIGHT: #fff 1px solid;
      BORDER-TOP: #fff 1px solid;
       DISPLAY: none; 
       Z-INDEX: 9999; 
       BACKGROUND: #fdfce9; 
       LEFT: 50%; 
       MARGIN: -220px 0px 0px -250px; 
       BORDER-LEFT: #fff 1px solid; 
       WIDTH: 500px; 
       BORDER-BOTTOM: #fff 1px solid; 
       POSITION: absolute; 
       TOP: 50%; 
       HEIGHT: 400px; 
       TEXT-ALIGN: left
}
UNKNOWN {
     POSITION: fixed
}
#overlay {
      DISPLAY: none;
      Z-INDEX: 5000; FILTER: alpha(opacity=80); 
      LEFT: 0px; 
      WIDTH: 100%; 
      POSITION: absolute; 
      TOP: 0px; 
      HEIGHT: 100%; 
      BACKGROUND-COLOR: #000; moz-opacity: 0.8; opacity: .80
}
UNKNOWN {
    POSITION: fixed
}
.done#lightbox #lbLoadMessage {
      DISPLAY: none
}
.done#lightbox #lbContent {
      DISPLAY: block
}
.loading#lightbox #lbContent {
      DISPLAY: none
}
.loading#lightbox #lbLoadMessage {
       DISPLAY: block
}
.done#lightbox IMG {
      WIDTH: 100%; HEIGHT: 100%
}
 
客户端脚本
由于浏览器对图层的支持不同,所以首先要确定客户端浏览器的类型。以下代码可用于判断客户端的浏览器和操作系统。
var detect = navigator.userAgent.toLowerCase();
var OS,browser,version,total,thestring;

function getBrowserInfo() {
       if (checkIt('konqueror')) {
            browser = "Konqueror";
            OS = "Linux";
       }
       else if (checkIt('safari')) browser = "Safari"
       else if (checkIt('omniWeb')) browser = "OmniWeb"
       else if (checkIt('opera')) browser = "Opera"
       else if (checkIt('Webtv')) browser = "WebTV";
       else if (checkIt('icab')) browser = "iCab"
       else if (checkIt('msie')) browser = "Internet Explorer"
       else if (!checkIt('compatible')) {
             browser = "Netscape Navigator"
            version = detect.charAt(8);
       }
       else browser = "An unknown browser";

       if (!version) version = detect.charAt(place + thestring.length);

       if(!OS) {
            if (checkIt('linux')) OS = "Linux";
            else if (checkIt('x11')) OS = "Unix";
            else if (checkIt('mac')) OS = "Mac"
            else if (checkIt('win')) OS = "Windows"
            else OS = "an unknown operating system";
       }
}

function checkIt(string) {
        place = detect.indexOf(string) + 1;
        thestring = string;
        return place;
}
下面看一下网页加载时需要添加的方法。有关网页加载和初始化方法代码如下:
//网页加载调用initialize和getBrowserInfo方法
Event.observe(window, 'load', initialize, false);
Event.observe(window, 'load', getBrowserInfo, false);
//未加载时清空缓存
Event.observe(window, 'unload', Event.unloadCache, false);
//初始化方法
function initialize(){
        //调用该方法为该页添加覆盖层和高亮显示层
        addLightboxMarkup();
        //为每个可高亮显示的元素创建lightbox对象
        lbox = document.getElementsByClassName('lbOn');
        for(i = 0; i < lbox.length; i++) {
                    valid = new lightbox(lbox[i]);
        }
}

// 使用Dom方法创建覆盖层和高亮层
function addLightboxMarkup() {
        bod = document.getElementsByTagName('body')[0];
        overlay = document.createElement('div');
        overlay.id = 'overlay';
        lb = document.createElement('div');
        lb.id = 'lightbox';
        lb.className = 'loading';
        lb.innerHTML = '<div id="lbLoadMessage">' +
                                           '<p>Loading</p>' +
                                           '</div>';
        bod.appendChild(overlay);
        bod.appendChild(lb);
}
封装lightbox类
初始化数据时,为每个可高亮显示的链接创建了lightbox对象。该类的代码具体实现如下:
var lightbox = Class.create();

lightbox.prototype = {
       yPos : 0,
       xPos : 0,
      //构造方法,ctrl为创建该对象的元素
       initialize: function(ctrl) {
              //将该元素的链接赋值给this.content
              this.content = ctrl.href;
              //为该元素添加onclick事件activate方法
              Event.observe(ctrl, 'click', this.activate.bindAsEventListener(this), false);
              ctrl.onclick = function(){return false;};
       },

       //当单击链接时
       activate: function(){
              if (browser == 'Internet Explorer'){//判断为IE浏览器
                     this.getScroll();
                     this.prepareIE('100%', 'hidden');
                     this.setScroll(0,0);
                     this.hideSelects('hidden');//隐藏所有的<select>标记
              }
              //调用该类中的displayLightbox方法
              this.displayLightbox("block");
      },

      prepareIE: function(height, overflow){
            bod = document.getElementsByTagName('body')[0];
            bod.style.height = height;
            bod.style.overflow = overflow;
  
            htm = document.getElementsByTagName('html')[0];
            htm.style.height = height;
            htm.style.overflow = overflow; 
      },

      hideSelects: function(visibility){
           selects = document.getElementsByTagName('select');
           for(i = 0; i < selects.length; i++) {
                   selects[i].style.visibility = visibility;
            }
      },

      getScroll: function(){
            if (self.pageYOffset) {
                    this.yPos = self.pageYOffset;
            } else if (document.documentElement && document.documentElement.scrollTop){
                    this.yPos = document.documentElement.scrollTop; 
            } else if (document.body) {
                    this.yPos = document.body.scrollTop;
            }
      },

      setScroll: function(x, y){
            window.scrollTo(x, y); 
      },

      displayLightbox: function(display){
            //将覆盖层显示
            $('overlay').style.display = display;
            //将高亮层显示
            $('lightbox').style.display = display;
            //如果不是隐藏状态,则调用该类中的loadInfo方法
            if(display != 'none') this.loadInfo();
      },

      //该方法发送Ajax请求
      loadInfo: function() {
            //当请求完成后调用本类中processInfo方法
            var myAjax = new Ajax.Request(
          this.content,
          {method: 'get', parameters: "", onComplete: this.processInfo.bindAsEvent Listener (this)}
           );

      },
      // 将返回的文本信息显示到高亮层上
      processInfo: function(response){
           //获得返回的文本数据
           var result = response.responseText;
           //显示到高亮层
           info = "<div id='lbContent'>" + result + "</div>";
           //在info元素前插入一个元素
           new Insertion.Before($('lbLoadMessage'), info)
           //改变该元素的class name的值
           $('lightbox').className = "done"; 
           //调用本类中actions方法
           this.actions();
           var ctrl=$('lightbox');
           //为高亮层添加事件处理方法reset
          Event.observe(ctrl, 'click', this.reset.bindAsEventListener(this), false);
           ctrl.onclick = function(){return false;};
      },
      //恢复初始状态 
      reset:function(){
            //隐藏覆盖层
           $('overlay').style.display="none";
           //清空返回数据
            $('lbContent').innerHTML="";
            //隐藏高亮层
           $('lightbox').style.display="none";
     },
     // Search through new links within the lightbox, and attach click event
     actions: function(){
           lbActions = document.getElementsByClassName('lbAction');
           for(i = 0; i < lbActions.length; i++) {
                   Event.observe(lbActions[i], 'click', this[lbActions[i].rel].bindAs EventListener(this), false);
                   lbActions[i].onclick = function(){return false;};
           }

     }
}

提示:由于该对象比较复杂,读者可以仔细参阅代码的注释部分。


服务器端代码

服务器端首先获得查询中的“id”值,如果该值为null或为空,则设置为默认值。然后判断该值,并且返回相应的一段字符串信息。处理请求的getInfojsp页面代码如下:
<%@ page language="java" import="java.util.*"%>
<%
//获得请求中id的值
  String imgID = request.getParameter("id");
  if (imgID==null||imgID.equals(""))//如果为null或为空
      imgID="one";//设定为默认值
  if ( imgID.equals("one"))//如果为one
  {
%>
<h3 id="cartitle" style="border-bottom: 1px solid #C0C0C0; margin-bottom: -5px">Porsche Carrera GT</h3>
<p>The Carrera GT has a 5.7 litre V10 internal combustion engine that produces 
  605 SAE horsepower (451 kW). Porsche claims it will accelerate from 0 to 100 
  km/h (62 mph) in 3.9 seconds and has a maximum speed of 330 km/h (204 mph). 
  With 605 hp, the car weighs 1,380 kg (3,042 lb). The Carrera GT is only 
  offered with a six-speed manual transmission, in contrast to its rival the 
  Ferrari Enzo that is only offered with sequential manual transmission. Also 
  the Carrera GT is significantly less expensive than the Ferrari Enzo. The 
  Ferrari Enzo is priced around $660,000 to the Carrera GT's $440,000. The 
  Carrera GT is known for its high quality and reliability which makes it one of 
  the best supercars ever.
<%}else{//否则
%>
<h3 id="cartitle" style="border-bottom: 1px solid #C0C0C0; margin-bottom: -5px">Ferrari Testarossa</h3>
<p>The Ferrari Testarossa is an V12 mid-engined sports car made by Ferrari. 
  The name, which means &quot;red head&quot;, comes from the red painted cylinder heads on 
  the flat-12 engine. The engine was technically a 180?V engine since it shared 
  flat-plane crankshaft pins with opposing cylinders. Output was 390 hp (291 
  kW), and the car won many comparison tests and admirers - it was featured on 
  the cover of Road &amp; Track magazine nine times in just five years. Almost 
  10,000 Testarossas, 512TRs, and 512Ms were produced, making this one of the 
  most common Ferrari models despite its high price and exotic design.
<%}%>
 

新浪BLOG提示框

<script language="javascript" type="text/javascript" src="
<body>
 
  <input type="text"  id="Text1"  >
  <input type="button" onclick="CheckText();" value="单击我哦">
</body> 
</html>
 

<script language="javascript">
 
 //Author yaosansi
function CheckText()

 if($("Text1").value.length==0)
 
 {
   alert("请输入内容.");
 } 
 else
 { 
  alert($('Text1').value)
 ;
 }
 
}
</script>
<br />
 
<br />

<br />

<br />

Author:yaosansi
Site:<a href="
      <td class="f_01">
   <table width="100%" border="0" cellspacing="0" cellpadding="4">
        <tr>
          <td align="left">  <img src="
http://www.pcauto.com.cn/images/piclib/index_15.gif" width="10" height="12" /> 
              
              <a class="linkwhite" href="BLOCKED SCRIPTvoid(0);" onclick="m_expandtree('TREE_1');"><font class="STYLE2">国产热门品牌</font></a>
              <img id="_LTREE_1" src="http://www.pcauto.com.cn/images/piclib/m_index_29.gif" onclick="m_expandtree('TREE_1');">
              
          </td>
        </tr>
      </table>
   </td>
    </tr>
  <!--树二层-->
    
    <tr id="TREE_1" style="display:;" bgcolor="#34638D">
      <td><table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#34638D">
        
        <tr onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
          <td class="f_02"><table width="100%" border="0" cellpadding="4" cellspacing="0">
            <tr  onMouseOver="showDisplayLayers('Layer_1926');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1926');mout(this,'#F5F5F5')">
              <td align="left">    <img src="http://www.pcauto.com.cn/images/piclib/m_index_57.jpg" width="12" height="11" /> 
                  
                    
                    <a class="linkwhite" href="BLOCKED SCRIPTvoid(0);"><font class="STYLE2">广州丰田</font></a>
                    
                  
              </td>
              <td width="10" align="left">
                  <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                  <DIV ID="Layer_1926" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                  <!-- 树三层 -->
                   <table border="0" cellspacing="0" cellpadding="0" width="200">
                      
                      <tr>
                        <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgColor=#F5F5F5>
                             <TR onMouseOver="mover(this,'#EBEBEB')" onMouseOut="mout(this,'#F5F5F5')">
                                <TD width="10"></TD>
                                <TD><span class="STYLE2">·</span>
                                    <a class="linkwhite" href="m_node_photos.jsp?nodeId=1927" target="_blank"><font class="STYLE2">凯美瑞</font></a></TD>
                              </TR>
                          </TABLE></td>
                      </tr>
                      
                   </table>
                </DIV>
              </td>
            </tr>
          </table></td>
        </tr>
        <!-- 树三层 -->
        
        
        <tr onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
          <td class="f_02"><table width="100%" border="0" cellpadding="4" cellspacing="0">
            <tr  onMouseOver="showDisplayLayers('Layer_52');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_52');mout(this,'#F5F5F5')">
              <td align="left">    <img src="http://www.pcauto.com.cn/images/piclib/m_index_57.jpg" width="12" height="11" /> 
                  
                    
                    <a class="linkwhite" href="BLOCKED SCRIPTvoid(0);"><font class="STYLE2">北京现代</font></a>
                    
                  
              </td>
              <td width="10" align="left">
                  <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                  <DIV ID="Layer_52" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                  <!-- 树三层 -->
                   <table border="0" cellspacing="0" cellpadding="0" width="200">
                      
                      <tr>
                        <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgColor=#F5F5F5>
                             <TR onMouseOver="mover(this,'#EBEBEB')" onMouseOut="mout(this,'#F5F5F5')">
                                <TD width="10"></TD>
                                <TD><span class="STYLE2">·</span>
                                    <a class="linkwhite" href="m_node_photos.jsp?nodeId=1421" target="_blank"><font class="STYLE2">雅绅特</font></a></TD>
                              </TR>
                          </TABLE></td>
                      </tr>
                      
                      <tr>
                        <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgColor=#F5F5F5>
                             <TR onMouseOver="mover(this,'#EBEBEB')" onMouseOut="mout(this,'#F5F5F5')">
                                <TD width="10"></TD>
                                <TD><span class="STYLE2">·</span>
                                    <a class="linkwhite" href="m_node_photos.jsp?nodeId=55" target="_blank"><font class="STYLE2">索纳塔</font></a></TD>
                              </TR>
                          </TABLE></td>
                      </tr>
                      
                      <tr>
                        <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgColor=#F5F5F5>
                             <TR onMouseOver="mover(this,'#EBEBEB')" onMouseOut="mout(this,'#F5F5F5')">
                                <TD width="10"></TD>
                                <TD><span class="STYLE2">·</span>
                                    <a class="linkwhite" href="m_node_photos.jsp?nodeId=53" target="_blank"><font class="STYLE2">途胜</font></a></TD>
                              </TR>
                          </TABLE></td>
                      </tr>
                      
                      <tr>
                        <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgColor=#F5F5F5>
                             <TR onMouseOver="mover(this,'#EBEBEB')" onMouseOut="mout(this,'#F5F5F5')">
                                <TD width="10"></TD>
                                <TD><span class="STYLE2">·</span>
                                    <a class="linkwhite" href="m_node_photos.jsp?nodeId=56" target="_blank"><font class="STYLE2">伊兰特</font></a></TD>
                              </TR>
                          </TABLE></td>
                      </tr>
                      
                      <tr>
                        <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgColor=#F5F5F5>
                             <TR onMouseOver="mover(this,'#EBEBEB')" onMouseOut="mout(this,'#F5F5F5')">
                                <TD width="10"></TD>
                                <TD><span class="STYLE2">·</span>
                                    <a class="linkwhite" href="m_node_photos.jsp?nodeId=54" target="_blank"><font class="STYLE2">御翔</font></a></TD>
                              </TR>
                          </TABLE></td>
                      </tr>
                      
                   </table>
                </DIV>
              </td>
            </tr>
          </table></td>
        </tr>
      

      </table></td>
    </tr>
    
    
    <tr bgcolor="#1C3259" onMouseOver="mover(this,'#5B7AB2')" onMouseOut="mout(this,'#1C3259')">
      <td class="f_01">
   <table width="100%" border="0" cellspacing="0" cellpadding="4">
        <tr>
          <td align="left">  <img src="http://www.pcauto.com.cn/images/piclib/index_15.gif" width="10" height="12" /> 
              
              <a class="linkwhite" href="BLOCKED SCRIPTvoid(0);" onclick="m_expandtree('TREE_2');"><font class="STYLE2">国外热门品牌</font></a>
              <img id="_LTREE_2" src="http://www.pcauto.com.cn/images/piclib/m_index_12.gif" onclick="m_expandtree('TREE_2');">
              
          </td>
        </tr>
      </table>
   </td>
    </tr>

    <!-- 树二层 -->
    
    <tr id="TREE_2" style="display:none;" bgcolor="#34638D">
      <td><table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#34638D">
        
        <tr onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
          <td class="f_02"><table width="100%" border="0" cellpadding="4" cellspacing="0">
            <tr >
              <td align="left">    <img src="http://www.pcauto.com.cn/images/piclib/m_index_57.jpg" width="12" height="11" /> 
                  
                    
                    <a class="linkwhite" href="BLOCKED SCRIPTvoid(0)" onclick="m_expandtree('TREE_1011');"><font class="STYLE2">美洲品牌</font></a>
                    <img id="_LTREE_1011" src="http://www.pcauto.com.cn/images/piclib/m_index_12.gif" onclick="m_expandtree('TREE_1011');">
                    
                  
              </td>
              <td width="10" align="left"></td>
            </tr>
          </table></td>
        </tr>
        <!-- 树三层 -->
        
        <tr id="TREE_1011" style="display:none;"><td><table width="100%" border="0" cellpadding="4" cellspacing="0">
            
            <tr onMouseOver="showDisplayLayers('Layer_1892');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1892');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">ACURA(讴歌)</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1892" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1894" target="_blank"><font class="STYLE2">ACURA RL</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1893" target="_blank"><font class="STYLE2">ACURA TL</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1562');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1562');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">别克</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1562" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1563" target="_blank"><font class="STYLE2">Enclave概念车</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1239');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1239');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">悍马</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1239" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1240" target="_blank"><font class="STYLE2">06款H3</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1236');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1236');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">林肯</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1236" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1741" target="_blank"><font class="STYLE2">Zephyr</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1502" target="_blank"><font class="STYLE2">MKZ</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1442" target="_blank"><font class="STYLE2">MKX</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1237" target="_blank"><font class="STYLE2">Navigator(领航员)</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1107');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1107');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">庞蒂克</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1107" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1108" target="_blank"><font class="STYLE2">GTO</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1064');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1064');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">雪佛兰</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1064" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1666" target="_blank"><font class="STYLE2">Captiva</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1521" target="_blank"><font class="STYLE2">Camaro概念车</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1427" target="_blank"><font class="STYLE2">Corvette Z06</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1287" target="_blank"><font class="STYLE2">Aveo WTCC R+</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1265" target="_blank"><font class="STYLE2">06款HHR 2LT</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1099" target="_blank"><font class="STYLE2">T2X 概念车</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1088" target="_blank"><font class="STYLE2">雪佛兰SSR</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1065" target="_blank"><font class="STYLE2">雪佛兰Tahoe</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1050');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1050');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">道奇</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1050" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1522" target="_blank"><font class="STYLE2">Hornet概念车</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1266" target="_blank"><font class="STYLE2">2006 Charger R/T</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1054" target="_blank"><font class="STYLE2">SRT8</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1049');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1049');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">凯迪拉克</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1049" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1730" target="_blank"><font class="STYLE2">STS-V</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1289" target="_blank"><font class="STYLE2">XLR-V</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1235" target="_blank"><font class="STYLE2">凯迪拉克CTS</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1084" target="_blank"><font class="STYLE2">凯迪拉克SRX</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1060" target="_blank"><font class="STYLE2">DTS Presidential Limousine</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1051" target="_blank"><font class="STYLE2">Escalade</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1035');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1035');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">福特</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1035" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1925" target="_blank"><font class="STYLE2">新Focus RS WRC06</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1822" target="_blank"><font class="STYLE2">福特概念车</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1474" target="_blank"><font class="STYLE2">07款Expedition</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1441" target="_blank"><font class="STYLE2">Focus RS</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1286" target="_blank"><font class="STYLE2">Explorer</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1104" target="_blank"><font class="STYLE2">蒙迪欧</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
            
            <tr onMouseOver="showDisplayLayers('Layer_1012');mover(this,'#EFEFEF')" onMouseOut="showDisplayLayers('Layer_1012');mout(this,'#F5F5F5')">
              <td class="f_02"><table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="left">      <span class="STYLE2">·</span><a class="linkwhite" href="#"><font class="STYLE2">克莱斯勒</font></a></td>
                  <td width="10" align="left">
                    <img src="http://www.pcauto.com.cn/images/piclib/m_index_59.jpg" width="12" height="12" />
                    <DIV ID="Layer_1012" STYLE="Z-INDEX: 44; WIDTH: 200px; POSITION: absolute; HEIGHT: 20px; display: none; left: 178;">
                      <!-- 树四层 -->
                       <table border="0" cellspacing="0" cellpadding="0" width="200">
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1383" target="_blank"><font class="STYLE2">Aspen</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1013" target="_blank"><font class="STYLE2">300C</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                          <tr>
                            <td align="left" class="f_04"><TABLE width="100%" border=0 cellPadding=4 cellSpacing=0 bgcolor=#F5F5F5>
                                 <TR onMouseOver="mover(this,'#EFEFEF')" onMouseOut="mout(this,'#F5F5F5')">
                                    <TD width="10"></TD>
                                    <TD><span class="STYLE2">·</span>
                                         <a class="linkwhite" href="m_node_photos.jsp?nodeId=1014" target="_blank"><font class="STYLE2">Grand Voyager(大捷龙)</font></a></TD>
                                  </TR>
                              </TABLE></td>
                          </tr>
                          
                       </table>
                    </DIV>
                  </td>
                </tr>
              </table></td>
            </tr>
           

          </table></td>
        </tr>

       

      </table></td>
    </tr>
    </table>
      <script src="attachments/month_0606/n200662717755.js"></script>
      <div>

            http://www.yaosansi.com
   <div/>      
  </body>
 </html>
      
      
     

 

 

使用Modello编写JavaScript类

一,背景

回顾一下编程语言的发展,不难发现这是一个不断封装的过程:从最开始的汇编语言,到面向过程语言,然后到面向对象语言,再到具备面向对象特性的脚本 语言,一层一层封装,一步一步减轻程序员的负担,逐渐提高编写程序的效率。这篇文章是关于 JavaScript 的,所以我们先来了解一下 JavaScript 是一种怎样的语言。到目前为止,JavaScript 是一种不完全支持面向对象特性的脚本语言。之所以这样说是因为 JavaScript 的确支持对象的概念,在程序中我们看到都是对象,可是 Javascipt 并不支持类的封装和继承。曾经有过 C++、Java或者 php、python 编程经验的读者都会知道,这些语言允许我们使用类来设计对象,并且这些类是可继承的。JavaScript 的确支持自定义对象和继承,不过使用的是另外一种方式:prototype(中文译作:原型)。用过 JavaScript 的或者读过《设计模式》的读者都会了解这种技术,描述如下:

每个对象都包含一个 prototype 对象,当向对象查询一个属性或者请求一个方法的时候,运行环境会先在当前对象中查找,如果查找失败则查找其 prototype 对象。注意 prototype 也是一个对象,于是这种查找过程同样适用在对象的 prototype 对象中,直到当前对象的 prototpye 为空。

在 JavaScript 中,对象的 prototype 在运行期是不可见的,只能在定义对象的构造函数时,创建对象之前设定。下面的用法都是错误的:

														o2
														.
														prototype
														 = 
														o1
														;

														/*
这时只定义了 o2 的一个名为“prototype”的属性,
并没有将 o1 设为 o2 的 prototype。
*/
														
																

														
														// ---------------
														
																

														
														f2
														 = 
														function
														(){}
														;

														o2
														 = 
														new
														
														
														f2
														;

														f2
														.
														prototype
														 = 
														o1
														;

														/*
这时 o1 并没有成为 o2 的 prototype,
因为 o2 在 f2 设定 prototype 之前已经被创建。
*/
														
																

														
														// ---------------
														
																

														
														f1
														 = 
														function
														(){}
														;

														f2
														 = 
														function
														(){}
														;

														o1
														 = 
														new
														
														
														f1
														;

														f2
														.
														prototype
														 = 
														o1
														;

														o2
														 = 
														new
														
														
														f2
														;

														/*
同样,这时 o1 并不是 o2 的 prototype,
因为 JavaScript 不允许构造函数的 prototype 对象被其它变量直接引用。
*/
												

正确的用法应该是:

														f1
														 = 
														function
														(){}
														;

														f2
														 = 
														function
														(){}
														;

														f2
														.
														prototype
														 = 
														new
														
														
														f1
														;

														o2
														 = 
														new
														
														
														f2
														;
												

从上面的例子可以看出:如果你想让构造函数 F2 继承另外一个构造函数 F1 所定义的属性和方法,那么你必须先创建一个 F1 的实例对象,并立刻将其设为 F2 的 prototype。于是你会发现使用 prototype 这种继承方法实际上是不鼓励使用继承:一方面是由于 JavaScript 被设计成一种嵌入式脚本语言,比方说嵌入到浏览器中,用它编写的应用一般不会很大很复杂,不需要用到继承;另一方面如果继承得比较深,prototype 链就会比较长,用在查找对象属性和方法的时间就会变长,降低程序的整体运行效率。

二,问题

现在 JavaScript 的使用场合越来越多,web2.0 有一个很重要的方面就是用户体验。好的用户体验不但要求美工做得好,并且讲求响应速度和动态效果。很多有名的 web2.0 应用都使用了大量的 JavaScript 代码,比方说 FlickrGmail 等等。甚至有些人用 Javasript 来编写基于浏览器的 GUI,比方说 BackbaseQooxdoo 等等。于是 JavaScript 代码的开发和维护成了一个很重要的问题。很多人都不喜欢自己发明轮子,他们希望 JavaScript 可以像其它编程语言一样,有一套成熟稳定 Javasript 库来提高他们的开发速度和效率。更多人希望的是,自己所写的 JavaScript 代码能够像其它面向对象语言写的代码一样,具有很好的模块化特性和很好的重用性,这样维护起来会更方便。可是现在的 JavaScript 并没有很好的支持这些需求,大部分开发都要重头开始,并且维护起来很不方便。

三,已有解决方案

有需求自然就会有解决方案,比较成熟的有两种:

1,现在很多人在自己的项目中使用一套叫 prototype.js 的 JavaScript 库,那是由 MVC web 框架 Ruby on Rails 开发并使用 JavaScript 基础库。这套库设计精良并且具有很好的可重用性和跨浏览器特性,使用 prototype.js 可以大大简化客户端代码的开发工作。prototype.js 引入了类的概念,用其编写的类可以定义一个 initialize 的初始化函数,在创建类实例的时候会首先调用这个初始化函数。正如其名字,prototype.js 的核心还是 prototype,虽然提供了很多可复用的代码,但没有从根本上解决 JavaScript 的开发和维护问题。

2,使用 asp.net 的人一般都会听过或者用到一个叫 Atlas 的框架,那是微软的 AJAX 利器。Atlas 允许客户端代码用类的方法来编写,并且比 prototype.js 具备更好的面向对象特性,比方说定义类的私有属性和私有方法、支持继承、像java那样编写接口等等。Atlas 是一个从客户端到服务端的解决方案,但只能在 asp.net 中使用、版权等问题限制了其使用范围。

从根本上解决问题只有一个,就是等待 JavaScript2.0(或者说ECMAScript4.0)标准的出台。在下一版本的 JavaScript 中已经从语言上具备面向对象的特性。另外,微软的 JScript.NET 已经可以使用这些特性。当然,等待不是一个明智的方法。

四,Modello 框架

如果上面的表述让你觉得有点头晕,最好不要急于了解 Modello 框架,先保证这几个概念你已经能够准确理解:

  • JavaScript 构造函数:在 JavaScript 中,自定义对象通过构造函数来设计。运算符 new 加上构造函数就会创建一个实例对象
  • JavaScript 中的 prototype:如果将一个对象 P 设定为一个构造函数 F 的 prototype,那么使用 F 创建的实例对象就会继承 P 的属性和方法
  • 类:面向对象语言使用类来封装和设计对象。按类型分,类的成员分为属性和方法。按访问权限分,类的成员分为静态成员,私有成员,保护成员,公有成员
  • 类的继承:面向对象语言允许一个类继承另外一个类的属性和方法,继承的类叫做子类,被继承的类叫做父类。某些语言允许一个子类只能继承一个父类(单继承),某些语言则允许继承多个(多继承)
  • JavaScript 中的 closure 特性:函数的作用域就是一个 closure。JavaScript 允许在函数 O 中定义内部函数 I ,内部函数 I 总是可以访问其外部函数 O 中定义的变量。即使在外部函数 O 返回之后,你再调用内部函数 I ,同样可以访问外部函数 O 中定义的变量。也就是说,如果你在构造函数 C 中用 var 定义了一个变量V,用 this 定义了一个函数F,由 C 创建的实例对象 O 调用 O.F 时,F 总是可以访问到 V,但是用 O.V 这样来访问却不行,因为 V 不是用 this 来定义的。换言之,V 成了 O 的私有成员。这个特性非常重要,如果你还没有彻底搞懂,请参考这篇文章《Private Members in JavaScript》

搞懂上面的概念,理解下面的内容对你来说已经没有难度,开始吧!

如题,Modello 是一个允许并且鼓励你用 JavaScript 来编写类的框架。传统的 JavaScript 使用构造函数来自定义对象,用 prototype 来实现继承。在 Modello 中,你可以忘掉晦涩的 prototype,因为 Modello 使用类来设计对象,用类来实现继承,就像其它面向对象语言一样,并且使用起来更加简单。不信吗?请继续往下看。

使用 Modello 编写的类所具备如下特性:

  • 私有成员、公共成员和静态成员
  • 类的继承,多继承
  • 命名空间
  • 类型鉴别

Modello 还具有以下特性:

  • 更少的概念,更方便的使用方法
  • 小巧,只有两百行左右的代码
  • 设计期和运行期彻底分离,使用继承的时候不需要使用 prototype,也不需要先创建父类的实例
  • 兼容 prototype.js 的类,兼容 JavaScript 构造函数
  • 跨浏览器,跨浏览器版本
  • 开放源代码,BSD licenced,允许免费使用在个人项目或者商业项目中

下面介绍 Modello 的使用方法:

1,定义一个类

														Point
														 = 
														Class
														.
														create
														()
														;

														/*
创建一个类。用过 prototype.js 的人觉得很熟悉吧;)
*/
												

2,注册一个类

														Point
														.
														register
														(
														"
														Modello.Point
														"
														)
														;

														/*
这里"Modello"是命名空间,"Point"是类名,之间用"."分隔
如果注册成功,
Point.namespace 等于 "Modello",Point.classname 等于 "Point"。
如果失败 Modello 会抛出一个异常,说明失败原因。
*/
														
																

														
														Point
														.
														register
														(
														"
														Point
														"
														)
														; 
														// 这里使用默认的命名空间 "std"
														
																

														
														Class
														.
														register
														(
														Point
														, 
														"
														Point
														"
														)
														; 
														// 使用 Class 的 register 方法
												

3,获取已注册的类

														P
														 = 
														Class
														.
														get
														(
														"
														Modello.Point
														"
														)
														;

														P
														 = 
														Class
														.
														get
														(
														"
														Point
														"
														)
														; 
														// 这里使用默认的命名空间 "std"
												

4,使用继承

														ZPoint
														 = 
														Class
														.
														create
														(
														Point
														)
														; 
														// ZPoint 继承 Point
														
																

														
														ZPoint
														 = 
														Class
														.
														create
														(
														"
														Modello.Point
														"
														)
														; 
														// 继承已注册的类
														
																

														
														ZPoint
														 = 
														Class
														.
														create
														(
														Point1
														, 
														Point2
														[
														, ...
														])
														;

														/*
多继承。参数中的类也可以用已注册的类名来代替
*/
														
																

														
														/*
继承关系:
Point.subclasses 内容为 [ ZPoint ]
ZPoint.superclasses 内容为 [ Point ]
*/
												

5,定义类的静态成员

														Point
														.
														count
														 = 
														0
														;

														Point
														.
														add
														 = 
														function
														(
														x
														, 
														y
														)
														
														
														{
														
																

														
														return
														
														
														x
														 + 
														y
														;

														}
												

6,定义类的构造函数

														Point
														.
														construct
														 = 
														function
														(
														$
														self
														, $
														class
														)
														
														
														{
														
																

														
														// 用 "var" 来定义私有成员
														
																

														
														var
														
														
														_name
														 = 
														""
														;

														var
														
														
														_getName
														 = 
														function
														
														
														()
														
														
														{
														
																

														
														return
														
														
														_name
														;

														}
														
																

														
														// 用 "this" 来定义公有成员
														
																

														
														this
														.
														x
														 = 
														0
														;

														this
														.
														y
														 = 
														0
														;

														this
														.
														initialize
														 = 
														function
														
														
														(
														x
														, 
														y
														)
														
														
														{
														
														
														// 初始化函数
														
																

														
														this
														.
														x
														 = 
														x
														;

														this
														.
														y
														 = 
														y
														;
$
														class
														.
														count
														 += 
														1
														; 
														// 访问静态成员
														
																

														
														// 公有方法访问私有私有属性
														
																

														
														this
														.
														setName
														 = 
														function
														
														
														(
														name
														)
														
														
														{
														
																

														
														_name
														 = 
														name
														;

														}
														
																

														
														this
														.
														getName
														 = 
														function
														
														
														()
														
														
														{
														
																

														
														return
														
														
														_getName
														()
														;

														}
														
																

														
														this
														.
														toString
														 = 
														function
														
														
														()
														
														
														{
														
																

														
														return
														
														
														"
														Point(
														"
														 + 
														this
														.
														x
														 + 
														"
														, 
														"
														 + 
														this
														.
														y
														 + 
														"
														)
														"
														;

														}
														
																

														
														// 注意:initialize 和 toString 方法只有定义成公有成员才生效
														
																

														
														this
														.
														add
														 = 
														function
														()
														
														
														{
														
																

														
														// 调用静态方法,使用构造函数传入的 $class
														
																

														
														return
														 $
														class
														.
														add
														(
														this
														.
														x
														, 
														this
														.
														y
														)
														;

														}
														
																

														
														}
														
																

														
														ZPoint
														.
														construct
														 = 
														function
														(
														$
														self
														, $
														class
														)
														
														
														{
														
																

														
														this
														.
														z
														 = 
														0
														; 
														// this.x, this.y 继承自 Point
														
																

														
														// 重载 Point 的初始化函数
														
																

														
														this
														.
														initialize
														 = 
														function
														
														
														(
														x
														, 
														y
														, 
														z
														)
														
														
														{
														
																

														
														this
														.
														z
														 = 
														z
														;

														// 调用第一个父类的初始化函数,
														
																

														
														// 第二个父类是 $self.super1,如此类推。
														
																

														
														// 注意:这里使用的是构造函数传入的 $self 变量
														
																
$
														self
														.
														super0
														.
														initialize
														.
														call
														(
														this
														, 
														x
														, 
														y
														)
														;

														// 调用父类的任何方法都可以使用这种方式,但只限于父类的公有方法
														
																

														
														}
														
																

														
														// 重载 Point 的 toString 方法
														
																

														
														this
														.
														toString
														 = 
														function
														
														
														()
														
														
														{
														
																

														
														return
														
														
														"
														Point(
														"
														 + 
														this
														.
														x
														 + 
														"
														, 
														"
														 + 
														this
														.
														y
														 +

														"
														, 
														"
														 + 
														this
														.
														z
														 + 
														"
														)
														"
														;

														}
														
																

														
														}
														
																

														
														// 连写技巧
														
																

														
														Class
														.
														create
														()
														.
														register
														(
														"
														Modello.Point
														"
														)
														.
														construct
														 = 
														function
														(
														$
														self
														, $
														class
														)
														
														
														{
														
																

														
														// ...
														
																

														
														}
												

7,创建类的实例

														// 两种方法:new 和 create
														
																

														
														point
														 = 
														new
														
														
														Point
														(
														1
														, 
														2
														)
														;

														point
														 = 
														Point
														.
														create
														(
														1
														, 
														2
														)
														;

														point
														 = 
														Class
														.
														get
														(
														"
														Modello.Point
														"
														)
														.
														create
														(
														1
														, 
														2
														)
														;

														zpoint
														 = 
														new
														
														
														ZPoint
														(
														1
														, 
														2
														, 
														3
														)
														;
												

8,类型鉴别

														ZPoint
														.
														subclassOf
														(
														Point
														)
														; 
														// 返回 true
														
																

														
														point
														.
														instanceOf
														(
														Point
														)
														; 
														// 返回 true
														
																

														
														point
														.
														isA
														(
														Point
														)
														; 
														// 返回 true
														
																

														
														zpoint
														.
														isA
														(
														Point
														)
														; 
														// 返回 true
														
																

														
														zpoint
														.
														instanceOf
														(
														Point
														)
														; 
														// 返回 false
														
																

														
														// 上面的类均可替换成已注册的类名
												

以上就是 Modello 提供的全部功能。下面说说使用 Modello 的注意事项和建议:

  • 在使用继承时,传入的父类可以是使用 prototype.js 方式定义的类或者 JavaScript 方式定义的构造函数
  • 类实际上也是一个函数,普通的 prototype 的继承方式同样适用在用 Modello 定义的类中
  • 类可以不注册,这种类叫做匿名类,不能通过 Class.get 方法获取
  • 如果定义类构造函数时,像上面例子那样提供了 $self, $class 两个参数,Modello 会在创建实例时将实例本身传给 $self,将类本身传给 $class。$self 一般在访问父类成员时才使用,$class 一般在访问静态成员时才使用。虽然 $self和$class 功能很强大,但不建议你在其它场合使用,除非你已经读懂 Modello 的源代码,并且的确有特殊需求。更加不要尝试使用 $self 代替 this,这样可能会给你带来麻烦
  • 子类无法访问父类的私有成员,静态方法中无法访问私有成员
  • Modello 中私有成员的名称没有特别限制,不过用"_"开始是一个好习惯
  • Modello 不支持保护(protected)成员,如果你想父类成员可以被子类访问,则必须将父类成员定义为公有。你也可以参考 "this._property" 这样的命名方式来表示保护成员:)
  • 尽量将一些辅助性的计算复杂度大的方法定义成静态成员,这样可以提高运行效率
  • 使用 Modello 的继承和类型鉴别可以实现基本的接口(interface)功能,你已经发现这一点了吧;)
  • 使用多继承的时候,左边的父类优先级高于右边的父类。也就是说假如多个父类定义了同一个方法,最左边的父类定义的方法最终被继承

使用 Modello 编写的类功能可以媲美使用 Atlas 编写的类,并且使用起来更简洁。如果你想用 Modello 框架代替 prototype.js 中的简单类框架,只需要先包含 modello.js,然后去掉 prototype.js 中定义 Class 的几行代码即可,一切将正常运行。

 

如果你发现 Modello 的 bug,非常欢迎你通过 email 联系我。如果你觉得 Modello 应该具备更多功能,你可以尝试阅读一下源代码,你会发现 Modello 可以轻松扩展出你所需要的功能。

Modello 的原意为“大型艺术作品的模型”,希望 Modello 能够帮助你编写高质量的 JavaScript 代码。

5,下载

Modello 的完整参考说明和下载地址:http://modello.sourceforge.net

JS的IE和Firefox兼容性汇编
JS的IE和Firefox兼容性汇编(原作:hotman_x)- -
                                       


以下以 IE 代替 Internet Explorer,以 MF 代替 Mozzila Firefox

1. document.form.item 问题
    (1)现有问题:
        现有代码中存在许多 document.formName.item("itemName") 这样的语句,不能在 MF 下运行
    (2)解决方法:
        改用 document.formName.elements["elementName"]
    (3)其它
        参见 2

2. 集合类对象问题
    (1)现有问题:
        现有代码中许多集合类对象取用时使用 (),IE 能接受,MF 不能。
    (2)解决方法:
        改用 [] 作为下标运算。如:document.forms("formName") 改为 document.forms["formName"]。
        又如:document.getElementsByName("inputName")(1) 改为 document.getElementsByName("inputName")[1]
    (3)其它

3. window.event
    (1)现有问题:
        使用 window.event 无法在 MF 上运行
    (2)解决方法:
        MF 的 event 只能在事件发生的现场使用,此问题暂无法解决。可以这样变通:
        原代码(可在IE中运行):
            <input type="button" name="someButton" value="提交" onclick="BLOCKED SCRIPTgotoSubmit()"/>
            ...
            <script language="javascript">
                function gotoSubmit() {
                    ...
                    alert(window.event);    // use window.event
                    ...
                }
            </script>

        新代码(可在IE和MF中运行):
            <input type="button" name="someButton" value="提交" onclick="BLOCKED SCRIPTgotoSubmit(event)"/>
            ...
            <script language="javascript">
                function gotoSubmit(evt) {
                    evt = evt ? evt : (window.event ? window.event : null);
                    ...
                    alert(evt);             // use evt
                    ...
                }
            </script>
        此外,如果新代码中第一行不改,与老代码一样的话(即 gotoSubmit 调用没有给参数),则仍然只能在IE中运行,但不会出错。所以,这种方案 tpl 部分仍与老代码兼容。

4. HTML 对象的 id 作为对象名的问题
    (1)现有问题
        在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 MF 中不能。
    (2)解决方法
        用 getElementById("idName") 代替 idName 作为对象变量使用。

5. 用idName字符串取得对象的问题
    (1)现有问题
        在IE中,利用 eval(idName) 可以取得 id 为 idName 的 HTML 对象,在MF 中不能。
    (2)解决方法
        用 getElementById(idName) 代替 eval(idName)。

6. 变量名与某 HTML 对象 id 相同的问题
    (1)现有问题
        在 MF 中,因为对象 id 不作为 HTML 对象的名称,所以可以使用与 HTML 对象 id 相同的变量名,IE 中不能。
    (2)解决方法
        在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。
        此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误。
    (3)其它
        参见 问题4

7. event.x 与 event.y 问题
    (1)现有问题
        在IE 中,event 对象有 x, y 属性,MF中没有。
    (2)解决方法
        在MF中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
        故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
        event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。

        如果要完全一样,可以稍麻烦些:
        mX = event.x ? event.x : event.pageX;
        然后用 mX 代替 event.x
    (3)其它
        event.layerX 在 IE 与 MF 中都有,具体意义有无差别尚未试验。


8. 关于frame
   (1)现有问题
         在 IE中 可以用window.testFrame取得该frame,mf中不行
   (2)解决方法
         在frame的使用方面mf和ie的最主要的区别是:
如果在frame标签中书写了以下属性:
<frame src="xx.htm" id="frameId" name="frameName" />
那么ie可以通过id或者name访问这个frame对应的window对象
而mf只可以通过name来访问这个frame对应的window对象
例如如果上述frame标签写在最上层的window里面的htm里面,那么可以这样访问
ie: window.top.frameId或者window.top.frameName来访问这个window对象
mf: 只能这样window.top.frameName来访问这个window对象

另外,在mf和ie中都可以使用window.top.document.getElementById("frameId")来访问frame标签
并且可以通过window.top.document.getElementById("testFrame").src = 'xx.htm'来切换frame的内容
也都可以通过window.top.frameName.location = 'xx.htm'来切换frame的内容
关于frame和window的描述可以参见bbs的‘window与frame’文章
以及/test/js/test_frame/目录下面的测试
----adun 2004.12.09修改

9. 在mf中,自己定义的属性必须getAttribute()取得
10.在mf中没有  parentElement parement.children  而用
               parentNode parentNode.childNodes
   childNodes的下标的含义在IE和MF中不同,MF使用DOM规范,childNodes中会插入空白文本节点。
  一般可以通过node.getElementsByTagName()来回避这个问题。
   当html中节点缺失时,IE和MF对parentNode的解释不同,例如
   <form>
   <table>
        <input/>
   </table>
   </form>
   MF中input.parentNode的值为form, 而IE中input.parentNode的值为空节点

  MF中节点没有removeNode方法,必须使用如下方法 node.parentNode.removeChild(node)

11.const 问题
  (1)现有问题:
     在 IE 中不能使用 const 关键字。如 const constVar = 32; 在IE中这是语法错误。
  (2)解决方法:
     不使用 const ,以 var 代替。

12. body 对象
   MF的body在body标签没有被浏览器完全读入之前就存在,而IE则必须在body完全被读入之后才存在

13. url encoding
在js中如果书写url就直接写&不要写&例如var url = 'xx.jsp?objectName=xx&objectEvent=xxx';
frm.action = url那么很有可能url不会被正常显示以至于参数没有正确的传到服务器
一般会服务器报错参数没有找到
当然如果是在tpl中例外,因为tpl中符合xml规范,要求&书写为&
一般MF无法识别js中的&


14. nodeName 和 tagName 问题
  (1)现有问题:
     在MF中,所有节点均有 nodeName 值,但 textNode 没有 tagName 值。在 IE 中,nodeName 的使用好象
     有问题(具体情况没有测试,但我的IE已经死了好几次)。
  (2)解决方法:
     使用 tagName,但应检测其是否为空。

15. 元素属性
   IE下 input.type属性为只读,但是MF下可以修改


16. document.getElementsByName() 和 document.all[name] 的问题
  (1)现有问题:
     在 IE 中,getElementsByName()、document.all[name] 均不能用来取得 div 元素(是否还有其它不能取的元素还不知道)。
公有成员、私有成员和静态成员

实现类的公有成员
前面定义的任何类成员都属于公有成员的范畴,该类的任何实例都对外公开这些属性和方法。

实现类的私有成员
私有成员即在类的内部实现中可以共享的成员,不对外公开。JavaScript中并没有特殊的机制来定义私有成员,但可以用一些技巧来实现这个功能。
这个技巧主要是通过变量的作用域性质来实现的,在JavaScript中,一个函数内部定义的变量称为局部变量,该变量不能够被此函数外的程序所访问,却可以被函数内部定义的嵌套函数所访问。在实现私有成员的过程中,正是利用了这一性质。
前面提到,在类的构造函数中可以为类添加成员,通过这种方式定义的类成员,实际上共享了在构造函数内部定义的局部变量,这些变量就可以看作类的私有成员,例如:
<script language="JavaScript" type="text/javascript">
<!--
function class1(){
      var pp=" this is a private property"; //私有属性成员pp
      function pm(){  //私有方法成员pm,显示pp的值
             alert(pp);
      }
      this.method1=function(){
             //在公有成员中改变私有属性的值
             pp="pp has been changed";
      }
      this.method2=function(){
             pm();  //在公有成员中调用私有方法
      }
}
var obj1=new class1();
obj1.method1();  //调用公有方法method1
obj1.method2();  //调用公有方法method2
//-->
</script>
 
这样,就实现了私有属性pp和私有方法pm。运行完class1以后,尽管看上去pp和pm这些局部变量应该随即消失,但实际上因为class1是通过new来运行的,它所属的对象还没消失,所以仍然可以通过公开成员来对它们进行操作。
注意:这些局部变量(私有成员),被所有在构造函数中定义的公有方法所共享,而且仅被在构造函数中定义的公有方法所共享。这意味着,在prototype中定义的类成员将不能访问在构造体中定义的局部变量(私有成员)。
要使用私有成员,是以牺牲代码可读性为代价的。而且这种实现更多的是一种JavaScript技巧,因为它并不是语言本身具有的机制。但这种利用变量作用域性质的技巧,却是值得借鉴的。
 
实现静态成员
静态成员属于一个类的成员,它可以通过“类名.静态成员名”的方式访问。在JavaScript中,可以给一个函数对象直接添加成员来实现静态成员,因为函数也是一个对象,所以对象的相关操作,对函数同样适用。例如:
function class1(){//构造函数
}
//静态属性
class1.staticProperty="sample";
//静态方法
class1.staticMethod=function(){
      alert(class1.staticProperty);
}
//调用静态方法
class1.staticMethod();
通过上面的代码,就为类class1添加了一个静态属性和静态方法,并且在静态方法中引用了该类的静态属性。
如果要给每个函数对象都添加通用的静态方法,还可以通过函数对象所对应的类Function来实现,例如:
//给类Function添加原型方法:show ArgsCount
Function.prototype.showArgsCount=function(){
      alert(this.length);    //显示函数定义的形参的个数
}
function class1(a){
      //定义一个类
}
//调用通过Function的prototype定义的类的静态方法showArgsCount
class1. showArgsCount ();
由此可见,通过Function的prototype原型对象,可以给任何函数都加上通用的静态成员,这在实际开发中可以起到很大的作用,比如在著名的prototype-1.3.1.js框架中,就给所有的函数定义了以下两个方法:
//将函数作为一个对象的方法运行
Function.prototype.bind = function(object) { 
  var __method = this; 
  return function() { 
     __method.apply(object, arguments); 
  } 

//将函数作为事件监听器
Function.prototype.bindAsEventListener = function(object) { 
  var __method = this; 
  return function(event) { 
    __method.call(object, event || window.event); 
  } 
}
这两个方法在prototype-1.3.1框架中起了很大的作用.
 

JavaScript类的实现

理解类的实现机制
在JavaScript中可以使用function关键字来定义一个“类”,如何为类添加成员。在函数内通过this指针引用的变量或者方法都会成为类的成员,例如:
function class1(){
      var s="abc";
      this.p1=s;
      this.method1=function(){
             alert("this is a test method");
      }
}
var obj1=new class1();
通过new class1()获得对象obj1,对象obj1便自动获得了属性p1和方法method1。
在JavaScript中,function本身的定义就是类的构造函数,结合前面介绍过的对象的性质以及new操作符的用法,下面介绍使用new创建对象的过程。
(1)当解释器遇到new操作符时便创建一个空对象;
(2)开始运行class1这个函数,并将其中的this指针都指向这个新建的对象;
(3)因为当给对象不存在的属性赋值时,解释器就会为对象创建该属性,例如在class1中,当执行到this.p1=s这条语句时,就会添加一个属性p1,并把变量s的值赋给它,这样函数执行就是初始化这个对象的过程,即实现构造函数的作用;
(4)当函数执行完后,new操作符就返回初始化后的对象。
通过这整个过程,JavaScript中就实现了面向对象的基本机制。由此可见,在JavaScript中,function的定义实际上就是实现一个对象的构造器,是通过函数来完成的。这种方式的缺点是:
? 将所有的初始化语句、成员定义都放到一起,代码逻辑不够清晰,不易实现复杂的功能。
? 每创建一个类的实例,都要执行一次构造函数。构造函数中定义的属性和方法总被重复的创建,例如:
this.method1=function(){
            alert("this is a test method");
      }
这里的method1每创建一个class1的实例,都会被创建一次,造成了内存的浪费。下一节介绍另一种类定义的机制:prototype对象,可以解决构造函数中定义类成员带来的缺点。
 
使用prototype对象定义类成员
上一节介绍了类的实现机制以及构造函数的实现,现在介绍另一种为类添加成员的机制:prototype对象。当new一个function时,该对象的成员将自动赋给所创建的对象,例如:
<script language="JavaScript" type="text/javascript">
<!--
//定义一个只有一个属性prop的类
function class1(){
      this.prop=1;
}
//使用函数的prototype属性给类定义新成员
class1.prototype.showProp=function(){
      alert(this.prop);
}
//创建class1的一个实例
var obj1=new class1();
//调用通过prototype原型对象定义的showProp方法
obj1.showProp();
//-->
</script>
prototype是一个JavaScript对象,可以为prototype对象添加、修改、删除方法和属性。从而为一个类添加成员定义。
了解了函数的prototype对象,现在再来看new的执行过程。
(1)创建一个新的对象,并让this指针指向它;
(2)将函数的prototype对象的所有成员都赋给这个新对象;
(3)执行函数体,对这个对象进行初始化操作;
(4)返回(1)中创建的对象。
和 上一节介绍的new的执行过程相比,多了用prototype来初始化对象的过程,这也和prototype的字面意思相符,它是所对应类的实例的原型。 这个初始化过程发生在函数体(构造器)执行之前,所以可以在函数体内部调用prototype中定义的属性和方法,例如:
<script language="JavaScript" type="text/javascript">
<!--
//定义一个只有一个属性prop的类
function class1(){
      this.prop=1;
      this.showProp();
}
//使用函数的prototype属性给类定义新成员
class1.prototype.showProp=function(){
      alert(this.prop);
}
//创建class1的一个实例
var obj1=new class1();
//-->
</script>
和上一段代码相比,这里在class1的内部调用了prototype中定义的方法showProp,从而在对象的构造过程中就弹出了对话框,显示prop属性的值为1。
需要注意,原型对象的定义必须在创建类实例的语句之前,否则它将不会起作用,例如:
<script language="JavaScript" type="text/javascript">
<!--
//定义一个只有一个属性prop的类
function class1(){
      this.prop=1;
      this.showProp();
}
//创建class1的一个实例
var obj1=new class1();
//在创建实例的语句之后使用函数的prototype属性给类定义新成员,只会对后面创建的对象有效
class1.prototype.showProp=function(){
      alert(this.prop);
}
//-->
</script>
这段代码将会产生运行时错误,显示对象没有showProp方法,就是因为该方法的定义是在实例化一个类的语句之后。
由此可见,prototype对象专用于设计类的成员,它是和一个类紧密相关的,除此之外,prototype还有一个重要的属性:constructor,表示对该构造函数的引用,例如:
function class1(){
      alert(1);
}
class1.prototype.constructor(); //调用类的构造函数
这段代码运行后将会出现对话框,在上面显示文字“1”,从而可以看出一个prototype是和一个类的定义紧密相关的。实际上:class1.prototype.constructor===class1。

一种JavaScript类的设计模式
前面已经介绍了如何定义一个类,如何初始化一个类的实例,且类可以在function定义的函数体中添加成员,又可以用prototype定义类的成员,编程的代码显得混乱。如何以一种清晰的方式来定义类呢?下面给出了一种类的实现模式。
在JavaScript 中,由于对象灵活的性质,在构造函数中也可以为类添加成员,在增加灵活性的同时,也增加了代码的复杂度。为了提高代码的可读性和开发效率,可以采用这种定 义成员的方式,而使用prototype对象来替代,这样function的定义就是类的构造函数,符合传统意义类的实现:类名和构造函数名是相同的。例 如:
function class1(){
      //构造函数
}
//成员定义
class1.prototype.someProperty="sample";
class1.prototype.someMethod=function(){
      //方法实现代码
}
虽然上面的代码对于类的定义已经清晰了很多,但每定义一个属性或方法,都需要使用一次class1.prototype,不仅代码体积变大,而且易读性还不够。为了进一步改进,可以使用无类型对象的构造方法来指定prototype对象,从而实现类的成员定义:
//定义一个类class1
function class1(){
      //构造函数
}
//通过指定prototype对象来实现类的成员定义
class1.prototype={
      someProperty:"sample",
      someMethod:function(){
          //方法代码
      },
      …//其他属性和方法.
}
上 面的代码用一种很清晰的方式定义了class1,构造函数直接用类名来实现,而成员使用无类型对象来定义,以列表的方式实现了所有属性和方法,并且可以在 定义的同时初始化属性的值。这也更象传统意义面向对象语言中类的实现。只是构造函数和类的成员定义被分为了两个部分,这可看成JavaScript中定义 类的一种固定模式,这样在使用时会更加容易理解。
注意:在一个类的成员之间互相引用,必须通过this指针来进行,例如在上面例子中的 someMethod方法中,如果要使用属性someProperty,必须通过this.someProperty的形式,因为在JavaScript 中每个属性和方法都是独立的,它们通过this指针联系在一个对象上。

深入认识JavaScript中的函数
概述
函 数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解。JavaScript中的函数不同于其他的语言,每个函数都是作 为一个对象被维护和运行的。通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递。在继续讲述之前,先看一下函数的使用语 法:
function func1(…){…}
var func2=function(…){…};
var func3=function func4(…){…};
var func5=new Function();
这些都是声明函数的正确语法。它们和其他语言中常见的函数或之前介绍的函数定义方式有着很大的区别。那么在JavaScript中为什么能这么写?它所遵循的语法是什么呢?下面将介绍这些内容。
 
认识函数对象(Function Object)
可以用function关键字定义一个函数,并为每个函数指定一个函数名,通过函数名来进行调用。在JavaScript解释执行时,函数都是被维护为一个对象,这就是要介绍的函数对象(Function Object)。
函 数对象与其他用户所定义的对象有着本质的区别,这一类对象被称之为内部对象,例如日期对象(Date)、数组对象(Array)、字符串对象 (String)都属于内部对象。这些内置对象的构造器是由JavaScript本身所定义的:通过执行new Array()这样的语句返回一个对象,JavaScript内部有一套机制来初始化返回的对象,而不是由用户来指定对象的构造方式。
在JavaScript 中,函数对象对应的类型是Function,正如数组对象对应的类型是Array,日期对象对应的类型是Date一样,可以通过new Function()来创建一个函数对象,也可以通过function关键字来创建一个对象。为了便于理解,我们比较函数对象的创建和数组对象的创建。先 看数组对象:下面两行代码都是创建一个数组对象myArray:
var myArray=[];
//等价于
var myArray=new Array();
同样,下面的两段代码也都是创建一个函数myFunction:
function myFunction(a,b){
      return a+b;
}
//等价于
var myFunction=new Function("a","b","return a+b");
通 过和构造数组对象语句的比较,可以清楚的看到函数对象本质,前面介绍的函数声明是上述代码的第一种方式,而在解释器内部,当遇到这种语法时,就会自动构造 一个Function对象,将函数作为一个内部的对象来存储和运行。从这里也可以看到,一个函数对象名称(函数变量)和一个普通变量名称具有同样的规范, 都可以通过变量名来引用这个变量,但是函数变量名后面可以跟上括号和参数列表来进行函数调用。
用new Function()的形式来创建一个函数不常见,因为一个函数体通常会有多条语句,如果将它们以一个字符串的形式作为参数传递,代码的可读性差。下面介绍一下其使用语法:
var funcName=new Function(p1,p2,...,pn,body);
参数的类型都是字符串,p1到pn表示所创建函数的参数名称列表,body表示所创建函数的函数体语句,funcName就是所创建函数的名称。可以不指定任何参数创建一个空函数,不指定funcName创建一个无名函数,当然那样的函数没有任何意义。
需要注意的是,p1到pn是参数名称的列表,即p1不仅能代表一个参数,它也可以是一个逗号隔开的参数列表,例如下面的定义是等价的:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
JavaScript引入Function类型并提供new Function()这样的语法是因为函数对象添加属性和方法就必须借助于Function这个类型。
函数的本质是一个内部对象,由JavaScript解释器决定其运行方式。通过上述代码创建的函数,在程序中可以使用函数名进行调用。本节开头列出的函数定义问题也得到了解释。注意可直接在函数声明后面加上括号就表示创建完成后立即进行函数调用,例如:
var i=function (a,b){
       return a+b;
}(1,2);
alert(i);
这段代码会显示变量i的值等于3。i是表示返回的值,而不是创建的函数,因为括号“(”比等号“=”有更高的优先级。这样的代码可能并不常用,但当用户想在很长的代码段中进行模块化设计或者想避免命名冲突,这是一个不错的解决办法。
需要注意的是,尽管下面两种创建函数的方法是等价的:
function funcName(){
       //函数体
}
//等价于
var funcName=function(){
       //函数体
}
但前面一种方式创建的是有名函数,而后面是创建了一个无名函数,只是让一个变量指向了这个无名函数。在使用上仅有一点区别,就是:对于有名函数,它可以出现在调用之后再定义;而对于无名函数,它必须是在调用之前就已经定义。例如:
<script language="JavaScript" type="text/javascript">
<!--
func();
var func=function(){
       alert(1)
}
//-->
</script>
这段语句将产生func未定义的错误,而:
<script language="JavaScript" type="text/javascript">
<!--
func();
function func(){
      alert(1)
}
//-->
</script>
则能够正确执行,下面的语句也能正确执行:
<script language="JavaScript" type="text/javascript">
<!--
func();
var someFunc=function func(){
      alert(1)
}
//-->
</script>
由此可见,尽管JavaScript是一门解释型的语言,但它会在函数调用时,检查整个代码中是否存在相应的函数定义,这个函数名只有是通过function funcName()形式定义的才会有效,而不能是匿名函数。
 
函数对象和其他内部对象的关系
除 了函数对象,还有很多内部对象,比如:Object、Array、Date、RegExp、Math、Error。这些名称实际上表示一个类型,可以通过 new操作符返回一个对象。然而函数对象和其他对象不同,当用typeof得到一个函数对象的类型时,它仍然会返回字符串“function”,而 typeof一个数组对象或其他的对象时,它会返回字符串“object”。下面的代码示例了typeof不同类型的情况:
alert(typeof(Function)));
alert(typeof(new Function()));
alert(typeof(Array));
alert(typeof(Object));
alert(typeof(new Array()));
alert(typeof(new Date()));
alert(typeof(new Object()));
运 行这段代码可以发现:前面4条语句都会显示“function”,而后面3条语句则显示“object”,可见new一个function实际上是返回一 个函数。这与其他的对象有很大的不同。其他的类型Array、Object等都会通过new操作符返回一个普通对象。尽管函数本身也是一个对象,但它与普 通的对象还是有区别的,因为它同时也是对象构造器,也就是说,可以new一个函数来返回一个对象,这在前面已经介绍。所有typeof返回 “function”的对象都是函数对象。也称这样的对象为构造器(constructor),因而,所有的构造器都是对象,但不是所有的对象都是构造 器。
既然函数本身也是一个对象,它们的类型是function,联想到C++、Java等面向对象语言的类定义,可以猜测到Function类型 的作用所在,那就是可以给函数对象本身定义一些方法和属性,借助于函数的prototype对象,可以很方便地修改和扩充Function类型的定义,例 如下面扩展了函数类型Function,为其增加了method1方法,作用是弹出对话框显示"function":
Function.prototype.method1=function(){
      alert("function");
}
function func1(a,b,c){
      return a+b+c;
}
func1.method1();
func1.method1.method1();
注 意最后一个语句:func1.method1.mehotd1(),它调用了method1这个函数对象的method1方法。虽然看上去有点容易混淆, 但仔细观察一下语法还是很明确的:这是一个递归的定义。因为method1本身也是一个函数,所以它同样具有函数对象的属性和方法,所有对 Function类型的方法扩充都具有这样的递归性质。
Function是所有函数对象的基础,而Object则是所有对象(包括函数对象)的基 础。在JavaScript中,任何一个对象都是Object的实例,因此,可以修改Object这个类型来让所有的对象具有一些通用的属性和方法,修改 Object类型是通过prototype来完成的:
Object.prototype.getType=function(){
       return typeof(this);
}
var array1=new Array();
function func1(a,b){
      return a+b;
}
alert(array1.getType());
alert(func1.getType());
上面的代码为所有的对象添加了getType方法,作用是返回该对象的类型。两条alert语句分别会显示“object”和“function”。
 
将函数作为参数传递
在 前面已经介绍了函数对象本质,每个函数都被表示为一个特殊的对象,可以方便的将其赋值给一个变量,再通过这个变量名进行函数调用。作为一个变量,它可以以 参数的形式传递给另一个函数,这在前面介绍JavaScript事件处理机制中已经看到过这样的用法,例如下面的程序将func1作为参数传递给 func2:
function func1(theFunc){
      theFunc();
}
function func2(){
      alert("ok");
}
func1(func2);
在最后一条语句中,func2作为一个对象传递给了func1的形参theFunc,再由func1内部进行theFunc的调用。事实上,将函数作为参数传递,或者是将函数赋值给其他变量是所有事件机制的基础。
例如,如果需要在页面载入时进行一些初始化工作,可以先定义一个init的初始化函数,再通过window.onload=init;语句将其绑定到页面载入完成的事件。这里的init就是一个函数对象,它可以加入window的onload事件列表。
 
传递给函数的隐含参数:arguments
当 进行函数调用时,除了指定的参数外,还创建一个隐含的对象——arguments。arguments是一个类似数组但不是数组的对象,说它类似是因为它 具有数组一样的访问性质,可以用arguments[index]这样的语法取值,拥有数组长度属性length。arguments对象存储的是实际传 递给函数的参数,而不局限于函数声明所定义的参数列表,例如:
function func(a,b){
     alert(a);
     alert(b);
     for(var i=0;i<arguments.length;i++){
           alert(arguments[i]);
     }
}
func(1,2,3);
代 码运行时会依次显示:1,2,1,2,3。因此,在定义函数的时候,即使不指定参数列表,仍然可以通过arguments引用到所获得的参数,这给编程带 来了很大的灵活性。arguments对象的另一个属性是callee,它表示对函数对象本身的引用,这有利于实现无名函数的递归或者保证函数的封装性, 例如使用递归来计算1到n的自然数之和:
var sum=function(n){
      if(1==n)return 1;
      else return n+sum(n-1);
}
alert(sum(100));
其中函数内部包含了对sum自身的调用,然而对于JavaScript来说,函数名仅仅是一个变量名,在函数内部调用sum即相当于调用一个全局变量,不能很好的体现出是调用自身,所以使用arguments.callee属性会是一个较好的办法:
var sum=function(n){
      if(1==n)return 1;
      else return n+arguments.callee(n-1);
}
alert(sum(100));
callee属性并不是arguments不同于数组对象的惟一特征,下面的代码说明了arguments不是由Array类型创建:
Array.prototype.p1=1;
alert(new Array().p1);
function func(){
       alert(arguments.p1);
}
func();
运行代码可以发现,第一个alert语句显示为1,即表示数组对象拥有属性p1,而func调用则显示为“undefined”,即p1不是arguments的属性,由此可见,arguments并不是一个数组对象。
 
函数的apply、call方法和length属性
JavaScript为函数对象定义了两个方法:apply和call,它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数的方式有所区别:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
从 函数原型可以看到,第一个参数都被取名为thisArg,即所有函数内部的this指针都会被赋值为thisArg,这就实现了将函数作为另外一个对象的 方法运行的目的。两个方法除了thisArg参数,都是为Function对象传递的参数。下面的代码说明了apply和call方法的工作方式:
//定义一个函数func1,具有属性p和方法A
function func1(){
      this.p="func1-";
      this.A=function(arg){
            alert(this.p+arg);
      }
}
//定义一个函数func2,具有属性p和方法B
function func2(){
      this.p="func2-";
      this.B=function(arg){
             alert(this.p+arg);
      }
}
var obj1=new func1();
var obj2=new func2();
obj1.A("byA");    //显示func1-byA
obj2.B("byB");    //显示func2-byB
obj1.A.apply(obj2,["byA"]); //显示func2-byA,其中[“byA”]是仅有一个元素的数组,下同
obj2.B.apply(obj1,["byB"]); //显示func1-byB
obj1.A.call(obj2,"byA");  //显示func2-byA
obj2.B.call(obj1,"byB");  //显示func1-byB
可以看出,obj1的方法A被绑定到obj2运行后,整个函数A的运行环境就转移到了obj2,即this指针指向了obj2。同样obj2的函数B也可以绑定到obj1对象去运行。代码的最后4行显示了apply和call函数参数形式的区别。
与arguments的length属性不同,函数对象还有一个属性length,它表示函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码将显示2:
function sum(a,b){
      return a+b;
}
alert(sum.length);
 

深入认识JavaScript中的this指针
this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象。在实现对象的方法时,可以使用this指针来获得该对象自身的引用。
和其他面向对象的语言不同,JavaScript中的this指针是一个动态的变量,一个方法内的this指针并不是始终指向定义该方法的对象的,在上一节讲函数的apply和call方法时已经有过这样的例子。为了方便理解,再来看下面的例子:
<script language="JavaScript" type="text/javascript">
<!--
//创建两个空对象
var obj1=new Object();
var obj2=new Object();
//给两个对象都添加属性p,并分别等于1和2
obj1.p=1;
obj2.p=2;
//给obj1添加方法,用于显示p的值
obj1.getP=function(){
      alert(this.p); //表面上this指针指向的是obj1
}
//调用obj1的getP方法
obj1.getP();
//使obj2的getP方法等于obj1的getP方法
obj2.getP=obj1.getP;
//调用obj2的getP方法
obj2.getP();
//-->
</script>
从 代码的执行结果看,分别弹出对话框显示1和2。由此可见,getP函数仅定义了一次,在不同的场合运行,显示了不同的运行结果,这是有this指针的变化 所决定的。在obj1的getP方法中,this就指向了obj1对象,而在obj2的getP方法中,this就指向了obj2对象,并通过this指 针引用到了两个对象都具有的属性p。
由此可见,JavaScript中的this指针是一个动态变化的变量,它表明了当前运行该函数的对象。由 this指针的性质,也可以更好的理解JavaScript中对象的本质:一个对象就是由一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一 个集合,而是可以动态的属于多个集合。这样,一个方法(集合元素)由谁调用,this指针就指向谁。实际上,前面介绍的apply方法和call方法都是 通过强制改变this指针的值来实现的,使this指针指向参数所指定的对象,从而达到将一个对象的方法作为另一个对象的方法运行。
每个对象集合 的元素(即属性或方法)也是一个独立的部分,全局函数和作为一个对象方法定义的函数之间没有任何区别,因为可以把全局函数和变量看作为window对象的 方法和属性。也可以使用new操作符来操作一个对象的方法来返回一个对象,这样一个对象的方法也就可以定义为类的形式,其中的this指针则会指向新创建 的对象。在后面可以看到,这时对象名可以起到一个命名空间的作用,这是使用JavaScript进行面向对象程序设计的一个技巧。例如:
var namespace1=new Object();
namespace1.class1=function(){
     //初始化对象的代码
}
var obj1=new namespace1.class1();
这里就可以把namespace1看成一个命名空间。
由于对象属性(方法)的动态变化特性,一个对象的两个属性(方法)之间的互相引用,必须要通过this指针,而其他语言中,this关键字是可以省略的。如上面的例子中:
obj1.getP=function(){
      alert(this.p); //表面上this指针指向的是obj1
}
这里的this关键字是不可省略的,即不能写成alert(p)的形式。这将使得getP函数去引用上下文环境中的p变量,而不是obj1的属性。
 
JavaScript实现抽象类
抽象类和虚函数
虚函数是类成员中的概念,是只做了一个声明而未实现的方法,具有虚函数的类就称之为抽象类,这些虚函数在派生类中才被实现。抽象类是不能实例化的,因为其中的虚函数并不是一个完整的函数,不能被调用。所以抽象类一般只作为基类被派生以后再使用。
和类的继承一样,JavaScript并没有任何机制用于支持抽象类。但利用JavaScript语言本身的性质,可以实现自己的抽象类。
在JavaScript实现抽象类
在 传统面向对象语言中,抽象类中的虚方法必须先被声明,但可以在其他方法中被调用。而在JavaScript中,虚方法就可以看作该类中没有定义的方法,但 已经通过this指针使用了。和传统面向对象不同的是,这里虚方法不需经过声明,而直接使用了。这些方法将在派生类中实现,例如:
<script language="JavaScript" type="text/javascript">
<!--
//定义extend方法
Object.extend = function(destination, source) { 
  for (property in source) { 
    destination[property] = source[property]; 
  } 
  return destination; 
}
Object.prototype.extend = function(object) { 
  return Object.extend.apply(this, [this, object]); 
}
//定义一个抽象基类base,无构造函数
function base(){}
base.prototype={
      initialize:function(){
               this.oninit(); //调用了一个虚方法
      }
}
//定义class1
function class1(){
      //构造函数
}
//让class1继承于base并实现其中的oninit方法
class1.prototype=(new base()).extend({
      oninit:function(){ //实现抽象基类中的oninit虚方法
             //oninit函数的实现
      }
});
//-->
</script>
这 样,当在class1的实例中调用继承得到的initialize方法时,就会自动执行派生类中的oninit()方法。从这里也可以看到解释型语言执行 的特点,它们只有在运行到某一个方法调用时,才会检查该方法是否存在,而不会向编译型语言一样在编译阶段就检查方法存在与否。JavaScript中则避 免了这个问题。当然,如果希望在基类中添加虚方法的一个定义,也是可以的,只要在派生类中覆盖此方法即可。例如:
//定义一个抽象基类base,无构造函数
function base(){}
base.prototype={
     initialize:function(){
          this.oninit(); //调用了一个虚方法
     },
     oninit:function(){} //虚方法是一个空方法,由派生类实现
}

使用抽象类的示例
仍然以prototype-1.3.1为例,其中定义了一个类的创建模型:
//Class是一个全局对象,有一个方法create,用于返回一个类
var Class = { 
   create: function() { 
     return function() { 
       this.initialize.apply(this, arguments); 
     }
   }
}
这里Class是一个全局对象,具有一个方法create,用于返回一个函数(类),从而声明一个类,可以用如下语法:
var class1=Class.create();
这样和函数的定义方式区分开来,使JavaScript语言能够更具备面向对象语言的特点。现在来看这个返回的函数(类):
function(){
      this.initialize.apply(this, arguments);
}
这 个函数也是一个类的构造函数,当new这个类时便会得到执行。它调用了一个initialize方法,从名字来看,是类的构造函数。而从类的角度来看,它 是一个虚方法,是未定义的。但这个虚方法的实现并不是在派生类中实现的,而是创建完一个类后,在prototype中定义的,例如prototype可以 这样写:
var class1=Class.create();
class1.prototype={
      initialize:function(userName){
                      alert(“hello,”+userName);
      }
}
这样,每次创建类的实例时,initialize方法都会得到执行,从而实现了将类的构造函数和类成员一起定义的功能。其中,为了能够给构造函数传递参数,使用了这样的语句:
function(){
      this.initialize.apply(this, arguments);
}
实际上,这里的arguments是function()中所传进来的参数,也就是new class1(args)中传递进来的args,现在要把args传递给initialize,巧妙的使用了函数的apply方法,注意不能写成:
this.initialize(arguments);
这是将arguments数组作为一个参数传递给initialize方法,而apply方法则可以把arguments数组对象的元素作为一组参数传递过去,这是一种很巧妙的实现。
尽 管这个例子在prototype-1.3.1中不是一个抽象类的概念,而是类的一种设计模式。但实际上可以把Class.create()返回的类看作所 有类的共同基类,它在构造函数中调用了一个虚方法initialize,所有继承于它的类都必须实现这个方法,完成构造函数的功能。它们得以实现的本质就 是对prototype的操作。

阅读更多
换一批

没有更多推荐了,返回首页