实现基于 Ajax 的无限级菜单
- 格式:doc
- 大小:38.00 KB
- 文档页数:10
花了两天时间。
研究AJAX,终于独立完成一个无限组的多级菜单联动功能。
主要特点:就是HTML静态页面可以无刷新的与PHP动态角本文件及数据库交互(这也是AJAX的核心目的)。
以下把代码贴出来。
供大家参考指正:ajax.js文件(位于根目录下js子目录)var xmlHttp;function createXmlHttp(){if(window.XMLHttpRequest){xmlHttp=new XMLHttpRequest();}else{xmlHttp=new ActiveXObject("Microsoft.XMLHttp");}}basic_inc.php(位于根目录下/include子目录下)<?php$DB_SERVER="localhost";$DB_NAME="ajax";$DB_USER="root";$DB_PASSWORD="";?>conn.php(位于根目录下/include子目录下)<?phprequire_once("dir_inc.php");require_once($ROOT_DIR."include/basic_inc.php");@ $db=mysql_connect($DB_SERVER,$DB_USER) or die ("faile!".mysql_error());@mysql_select_db($DB_NAME);?>dir_inc.php(位于根目标下/include子目录下)<?php$ROOT_DIR="../";?>select_menu.html(位于根目录下是核心前台文件)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>select_menu</title><script type="text/javascript" src="js/ajax.js">//这里引用创建xmlHttp对像的文件(对浏览器做过判断)</script><script type="text/javascript">var targetSelId; //申明一个全局变量用来存放当前要操作的对像的IDvar selArray;//申明一个全局数组。
实现基于Ajax 的无限级菜单特点:支持Form 的无闪提交(方法有点笨)支持MVC框架,即支持传统网页架构多线程并发请求(要语言支持线程) 动态加载文件,只加载有用的!处理了Ajax 框架臃肿的JS 文件问题采用no table 的全div + css 布局a.获得XMLHTTPReque对象,网上到处都找得到了,不多说:functionnewXMLHttpRequest() {var xmlreq = false;if (window.XMLHttpRequest) {xmlreq = new XMLHttpRequest();} else if (window.ActiveXObject) {try {xmlreq = new ActiveXObject("Msxml2.XMLHTTP");} catch (e1) {try {xmlreq = new ActiveXObject("Microsoft.XMLHTTP");} catch (e2) {}}}return xmlreq;这里提供一个通用的支持多浏览器的方法。
b. 提出异步请求// 这里用Bcandy 作为方法名是为了感谢一个对我来说很重要的人,她一直在支持我function Bcandy(Tid,url,parm,js) {if(url == ""){return;}// 这是一个加载信息提示框,也可以不要!document.getElementById("load").style.visibility = "visible";// 加载相应页面的JS 文件if(js != null){//加载JS文件LoadJS(js);}// 获取一个XMLHttpRequest 实例var req = newXMLHttpRequest();// 设置用来从请求对象接收回调通知的句柄函数var handlerFunction = getReadyStateHandler(req,Tid);req.onreadystatechange = handlerFunction;// 第三个参数表示请求是异步的req.open("POST", url, true);// 指示请求体包含form 数据req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");// 发送参数req.send(parm);}function getReadyStateHandler(req,Tid) {//返回一个监听XMLHttpRequest实例的匿名函数return function () {// 如果请求的状态是“完成”if (req.readyState == 4) {// 成功接收了服务器响应if (req.status == 200) {// 下面一句是重点,这里显示了返回信息的内容部分,也可以加以修改。
题目:thinkphp jquery与ajax实现省市区三级联动菜单thinkphp jquery与ajax实现省市县三级联动菜单本示例以省市区三级联动菜单为例:实现步骤:第一:先默认从数据库中读取所有的省份。
第二:通过jquery中的change事件,当省份的内容发生改变时,执行change事件,通过jquery 获得被选中的省份的value值,再后通过异步加载数据。
第三:与第二步相似,当用户选择城市时,会触发change事件,通过jquery 获得被选中的城市的value值,再次进行异步加载数据。
具体示例代码如下:RecruitmentAction.class.phpclass RecruitmentAction extends Action{public function chacity(){$code=I(post.code$city=M(where(array(provincecode$code))-select();echo "option value=请选择城市/optionif($city){foreach($city as $c){echo "option value=".$c[".$c[/optionpublic function chaarea(){ $code=I(post.code$area=M(where(array(citycode$code))-select();echo "option value=/optionif($area){foreach($area as $a){echo "option value=".$a[".$a[/optionpublic function chacitydefault(){ $code=I(post.code$city=M(where(array(provincecode$code))-select();if($city){foreach($city as $c){echo "option value=".$c[".$c[public function chaareadefault(){$code=I(post.code$area=M(where(array(citycode$code))-select();if($area){foreach($area as $a){echo "option value=".$a[".$a[/optionsendrecruitment.phpmeta charset="utf-8"/title省市县三级联动菜单/tiltescirpt src="/jquery/1.11.1/jquery.min.js"script$(function(){#sheng).change(function(){ var code=$(#sheng option:selected ).val();$.post(__URL__/chacity:code},function(data){ #city).html(data);#city).change(function(){ var code=$(#city option:selected ).val();$.post(__URL__/chaarea:code},function(data){).html(data);var code=$(#sheng option).eq(0).val();$.post(__URL__/chacitydefault:code},function(data){#city).html(data);var areacode=110100; $.post(__URL__/chaareadefault :areacode},function(data){ #area).html(data);/script/head$m=M(province$p=$m-id ascselect();input type="text" name="jobplace" value="" /select name="job_province" id="sheng" style="width:100px;"if($p){foreach($p as $v){option value="php echo $v[php echo $v[/option/selectselect name="job_city" id="city" style="width:100px;"/selectselect name="job_area" id="area" style="width:100px;"/select/body/html注:本示例中,控制器部分:chacitydefault(),chaareadefault()方法是为了默认页面加载时,执行一次,让省,市,与区进行显示。
PHP+Ajax三级联动菜单PHP+Ajax 三级联动菜单PHP+Ajax实例+注释演示2009-08-26 13:01一.使用ajax有以下固定步骤:1, 从页面触发Ajax的操作.2, 定义创建XMLHttpRequest对象的方法(建立一个XMLHttpRequest对象),也是就var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");//根据浏览器的不同有差异3, 然后建立一个函数,用来指定载入的数据来源!3.1,使用open方法打开数据来源(也就是我们要传入参数到DB查询的信息),但不意味着一定要发送数据显示!3.2,用onreadystatechange来指定数据装载的方式.(onreadystatechange是一个异步响应事件,就是因为它,ajax才那么完美.onreadystatechange事件中可以接收到服务器传回来的数据,通过分析和利用这些数据从而完成客户端的相应操作,onreadystatechange中的第三个参数你设为true,表示启用xmlHttp的异步通讯模式,这时你发出send命令后,浏览器还可以进行其它操作,如果设为false,浏览器就会进入无响应状态,直到xmlHttp接收完毕服务器传回的数据)3.3,使用send发送数据!4, 处理Ajax回传的数据(xml或text类型),使数据能按你的意愿现实在客户端.5, 回显到页面给用户.二,在网上看了一些资料,自己修改后,小小的整理主要出核心代码+精彩注释,全部贡献:index.php 客户端显示,包括执行AJAX的过程data.php 数据处理,查询数据,并回显/*************************index.php**********************/<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><!-------------------------------------------------------------- --省的字段是:province--市的字段是:city--县的字段是:area---------------------------------------------------------------------------><script type="text/javascript">/*********定义创建XMLHttpRequest对象的方法***************************************/var xmlHttp;//声明变量var requestType="";//声明初始类型为空function createXMLHttpRequest()//定义创建一个跨浏览器函数的开头{if(window.ActiveXObject)//ActiveXObject对象到找到的时候返回的是真,否则是假{xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");//这个是使用IE的方法创建XmlHttp}else if(window.XMLHttpRequest){xmlHttp=new XMLHttpRequest();//这个是使用非IE的方法创建XmlHttp}}/****************判断服务器响应的事件,如果返回是4则说明交互完成,判断标示头,**************************************************/function handleStateChange(){//判断返回的一个函数,来确定执行那个的函数if(xmlHttp.readystate==4){//4说明是执行交互完毕0 (未初始化)1 (正在装载)2 (装载完毕) 3 (交互中)4 (完成)if(xmlHttp.status==200){//http的一个报头说明成功找到if(type=="city"){//判断查询的类型showcity();//返回响应的显示}else if(type="area"){//判断响应的查询的类型showarea();//返回响应的显示}}}}/**************************城市的一个查询函数**********************************************************/function queryCity(citycode){//执行程序查询,查询城市的eval("document.form1.city.length=0;");//eval检查JScript 代码并执行.eval("document.form1.city.options.add(new Option('请选择城市','-1'));");createXMLHttpRequest();//调用创建XmlHttp的函数type="city";//表示类型,查询城市处理显示的时候需要用到varurl='data.php?provincecode='+citycode+'&n='+Math.random() ;//设定URL传值方法同时防止缓存xmlHttp.open("GET",url,true);//建立服务器连接,异步传输truexmlHttp.onreadystatechange=handleStateChange;//处理这个响应所需要的函数xmlHttp.send(null);//执行程序函数这里的中间的参数是因为GET原因}/**********************县区的一个查询函数***********************************************************/function queryArea(citycode){//查询程序eval("document.form1.area.length=0;");//eval检查 JScript 代码并执行.eval("document.form1.area.options.add(new Option('请选择县市','-1'));");createXMLHttpRequest();//调用创建XmlHttp的函数type="area";//查询县的varurl="data.php?citycode="+citycode+'&n='+Math.random();//设定URL传值方法同时防止缓存xmlHttp.open("GET",url,true);xmlHttp.onreadystatechange=handleStateChange;//处理响应的函数名xmlHttp.send(null);//执行程序函数这里的中间的参数是因为GET原因}/*********************一个显示函数*********************/function showcity(){//显示函数var a = xmlHttp.responseText.split('-');n = a.length;var aa = new Array();for(var i=0;i<n;i++){aa = a[i].split('**');eval("document.form1.city.options.add(newOption(aa[1],aa[0]));");//eval检查 JScript 代码并执行.}}function showarea(){var a = xmlHttp.responseText.split('-');n = a.length;var aa = new Array();for(var i=0;i<n;i++){aa = a[i].split('**');eval("document.form1.area.options.add(newOption(aa[1],aa[0]))");}//document.getElementById("area").innerHTML=xmlHttp.re sponseText;//捕获ID显示返回的数据}</script></head><body><?php$conn = mysql_connect("localhost","root","3661000");//链接数据库mysql_select_db("novel");//选择数据库mysql_query("set names 'utf8'");//设定字符集$sql = "select * from province";//查询数据库province表也就是省$result = mysql_query($sql);//执行语句赋值给变量><form name="form1"><!--输出表单头--><!--输出下拉列表框,并设定onchange响应事件,把省值传递过去--><select id='province' onchange='queryCity(this.options[this.selectedIndex].value)'> <!--输出下拉列表项值--><option value='-1' selected>请选择省份</option><?phpwhile($row=mysql_fetch_row($result)){//循环循环查询显示省输出数据显示echo "<option value='$row[1]'>$row[2]</option>\n";}></select><!--下拉列表项尾数--><select name="city" onchange="queryArea(this.options[this.selectedIndex].value)"></select> <!--显示数据的城市的位置--><select name="area"></select><!--显示数据的城市的位置--> </form><!--表单项结尾--></body></html>/***************data.php*****************/<?php$provincecode = $_GET['provincecode'];//接收省键值$citycode = $_GET['citycode'];//接收城市键值$conn = mysql_connect("localhost","root","3661000");//连接主机mysql_select_db("novel");//选择数据库mysql_query("set names 'utf8'");if($provincecode!=""){//如果传递过来的不为空则执行$sql = "select * from city where provincecode=$provincecode";//查询城市符合属于上边传递过来的省的字段$result = mysql_query($sql);//执行SQL查询语句while($row=mysql_fetch_row($result)){//循环记录集$xml .= $row[1]."**".$row[2]."-";}}if($citycode!=""){$sql = "select * from area where citycode=$citycode";$result = mysql_query($sql);while($row = mysql_fetch_row($result)){$xml .=$row[1]."**".$row[2]."-";}}$xml = substr($xml,0,strlen($xml)-1);//消掉最后的"-"echo $xml; //返回数据做回显。
如何通过前端框架实现无限滚动效果无限滚动效果是前端开发中常见的需求,它可以让页面在滚动到底部时自动加载更多内容,提升用户体验。
前端框架提供了便捷的实现方式,本文将介绍如何通过前端框架实现无限滚动效果。
一、什么是无限滚动效果无限滚动效果,也被称为无限加载或无限下拉,指的是当用户滚动到页面底部时,自动加载更多内容,无需手动点击或刷新页面。
这种效果常用于显示大量数据的列表、社交媒体的翻页、图片库等场景。
二、前端框架实现无限滚动效果前端框架如React、Angular、Vue等,提供了许多工具和组件,可以简化无限滚动效果的开发。
1. ReactReact是一种用于构建用户界面的JavaScript库,通过使用React,我们可以轻松地实现无限滚动效果。
可以借助React插件,如react-infinite-scroller或react-virtualized等。
react-infinite-scroller是一个常用的React插件,使用它可以实现无限滚动效果。
首先,安装该插件:npm install --save react-infinite-scroller然后,在需要实现无限滚动效果的组件中导入并使用该插件:import InfiniteScroll from 'react-infinite-scroller';class InfiniteList extends ponent {loadData(page) {// 根据页码加载数据}render() {return (<InfiniteScrollloadMore={this.loadData}hasMore={true}loader={<div className="loader" key={0}>Loading ...</div>}>{/* 呈现数据列表 */}</InfiniteScroll>);}}在上述代码中,loadData函数用于根据页码加载数据,loadMore属性指定了加载更多数据时调用的函数,hasMore属性指示是否还有更多数据可加载,loader属性定义了加载数据时显示的加载器。
php实现菜单⽆限极分类⼀、数据表结构CREATE TABLE `t_admin_privilege` (`f_id` int(11) NOT NULL AUTO_INCREMENT,`f_name` varchar(50) DEFAULT NULL COMMENT '⽬录名称',`f_parent_id` int(11) DEFAULT '0' COMMENT '⽗级id',`f_type` tinyint(4) DEFAULT NULL COMMENT '第⼏级⽬录',`f_url` varchar(255) DEFAULT NULL COMMENT '⽬录的链接地址',`f_createtime` int(10) DEFAULT NULL COMMENT '创建时间',`f_is_menu` tinyint(1) DEFAULT '1' COMMENT '1是菜单栏 2不是菜单栏',`f_icon` varchar(50) DEFAULT NULL COMMENT '⼩图标',`f_is_del` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否删除 1正在使⽤(未删除) 2删除',`f_sort` tinyint(5) DEFAULT NULL COMMENT '排序',PRIMARY KEY (`f_id`)) ENGINE=InnoDB AUTO_INCREMENT=335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT⼆、后台取数据(使⽤Yii框架)header("content-type:text/html;charset=utf-8"); //避免提⽰中⽂乱码$html = array();//获取菜单栏所有的数据$menu_record = T_admin_privilege::model()->findAll();$EData = new EData();$html['menu_list'] = $EData->push_info($menu_record);//1级⽬录$criteria_first = new CDbCriteria();$criteria_first->addCondition("f_type=1 AND f_is_menu=1 AND f_is_del=1");$criteria_first->order="f_id";//2级⽬录$criteria_second = new CDbCriteria();$criteria_second->addCondition("f_type=2 AND f_is_menu=1 AND f_is_del=1");$criteria_second->order="f_id";//3级⽬录$criteria_third = new CDbCriteria();$criteria_third->addCondition("f_type=3 AND f_is_menu=1 AND f_is_del=1");$criteria_third->order="f_id";//4级⽬录$criteria_fourth = new CDbCriteria();$criteria_fourth->addCondition("f_type=4 AND f_is_menu=1 AND f_is_del=1");$criteria_fourth->order="f_id";$menu_array = array();//菜单分为4级$first_list = T_admin_privilege::model()->findAll($criteria_first);$html['first_num'] = $first_num = count($first_list);$second_list = T_admin_privilege::model()->findAll($criteria_second);$html['second_num'] = $second_num = count($second_list);$third_list = T_admin_privilege::model()->findAll($criteria_third);$html['third_num'] = $third_num = count($third_list);$fourth_list = T_admin_privilege::model()->findAll($criteria_fourth);$html['fourth_num'] = $third_num = count($fourth_list);//⼀级⽬录foreach ($first_list as$first){$menu_array[$first->f_id] = array();}//⼆级⽬录foreach ($second_list as$second){$menu_array[$second->f_parent_id][$second->f_id] = array();}//三级⽬录foreach ($third_list as$third){foreach ($menu_array as$first_k => $menu){foreach ($menu as$second_k => $next){if ($second_k == $third->f_parent_id){$menu_array[$first_k][$second_k][$third->f_id] = array();}}}}//四级⽬录foreach ($fourth_list as$fourth){foreach ($menu_array as$first_k=>$second_menu){foreach ($second_menu as$second_k => $third_menu){foreach ($third_menu as$third_k => $firth_menu){if ($third_k == $fourth->f_parent_id){$menu_array[$first_k][$second_k][$third_k][$fourth->f_id] = 0;}}}}}$html['menu_array'] = $menu_array;//把数据单独放在⼀个页⾯,通过ajax加载$out = array('error' => 0,'content' => $this->renderPartial("ajax_get_menu_list_page", $html, true));echo CJSON::encode($out);三、html页⾯(ajax_get_menu_list_page页⾯,在pixed-admin框架下,也可引⼊jQuery,bootstrap修改样式)<div class="col-sm-12 menu_list" id="menu_list"><!--遍历⼀级⽬录 start--><?php foreach ($menu_array as $k=>$first_menu){?><div class="first_menu_list"><div class="first_menu menu"><?php if(count($first_menu)>0) {?><a href='javascript:;' class="is_show" f_id="<?php echo $menu_list[$k]['f_id'];?>">+</a><?php }else{?><i style="padding: 0 9px"></i><?php }?><input type="text" class="first_title title" name="first_title" value="<?php echo $menu_list[$k]['f_name']?>" f_id="<?php echo $menu_list[$k]['f_id'];?>" f_parent_id="0"><?php if(count($first_menu)<1) {?><input type="text" placeholder="请填写⽬录的路径地址" f_id="<?php echo $menu_list[$k]['f_id']?>" value="<?php echo $menu_list[$k]['f_url']?>" class="path_address"<div class="operation"><?php if (empty($menu_list[$k]['f_url']) ){?><a class="btn btn-xs btn-add second_add">添加</a><?php }?><?php if (count($first_menu)<=1){?><a class="btn btn-xs btn-del del first_del" f_id="<?php echo $menu_list[$k]['f_id']?>">删除</a><?php }?></div></div><!--遍历⼆级⽬录 start--><?php if(count($first_menu)>0){foreach ($first_menu as $first_k=>$second_menu){?><div class="second_menu_list <?php echo $menu_list[$first_k]['f_parent_id'];?>"><div class="second_menu menu"><input type="text" class="second_title title" name="second_title" value="<?php echo $menu_list[$first_k]['f_name']?>" f_id="<?php echo $menu_list[$first_k]['f_id'];?>" f_parent_id="<?php echo $menu_list[ <?php if(count($second_menu)<1) {?><input type="text" placeholder="请填写⽬录的路径地址" f_id="<?php echo $menu_list[$first_k]['f_id']?>" value="<?php echo $menu_list[$first_k]['f_url']?>"<div class="operation"><?php if(empty($menu_list[$first_k]['f_url'])) {?><a class="btn btn-xs btn-add third_add">添加</a><?php }?><?php if (count($second_menu)<=1){?><a class="btn btn-xs btn-del del second_del" f_id="<?php echo $menu_list[$first_k]['f_id']?>">删除</a><?php }?></div></div><!--遍历三级⽬录 start--><?php if (count($second_menu)>0){foreach ($second_menu as $second_k=>$third_menu){?><div class="third_menu_list"><div class="third_menu menu"><input type="text" class="third_title title" name="third_title" value="<?php echo $menu_list[$second_k]['f_name']?>" f_id="<?php echo $menu_list[$second_k]['f_id']?>" f_parent_id="<?php echo $menu <?php if(count($third_menu)<1) {?><input type="text" placeholder="请填写⽬录的路径地址" f_id="<?php echo $menu_list[$second_k]['f_id']?>" value="<?php echo $menu_list[$second_k]['f_url']?>"<div class="operation"><?php if(count($third_menu)>1) {?><a class="btn btn-xs btn-add fourth_add">添加</a><?php }?><?php if (count($third_menu)<=1){?><a class="btn btn-xs btn-del del third_del" f_id="<?php echo $menu_list[$second_k]['f_id']?>">删除</a><?php }?></div></div><!--遍历四级⽬录 start--><?php if (count($third_menu)>0){foreach ($third_menu as $third_k=>$fourth_menu){?><div class="fourth_menu menu"><input type="text" class="fourth_title title" name="fourth_title" value="<?php echo $menu_list[$third_k]['f_name']?>" f_id="<?php echo $menu_list[$third_k]['f_id']?>" f_parent_id="<?php echo $menu<input type="text" placeholder="请填写⽬录的路径地址" f_id="<?php echo $menu_list[$third_k]['f_id']?>" value="<?php echo $menu_list[$third_k]['f_url']?>" class="path_address"/><div class="operation"><a class="btn btn-xs btn-del del fourth_del" f_id="<?php echo $menu_list[$third_k]['f_id']?>">删除</a></div></div><?php }}?><!--遍历四级⽬录 end--></div><?php }}?><!--遍历三级⽬录 end--></div><?php }}?><!--遍历⼆级⽬录 end--></div><?php }?><!--遍历⼀级⽬录 end--></div>四、html页⾯(menu_list_page页⾯,在pixed-admin框架下,也可引⼊jQuery,bootstrap修改样式)、<div class="page-body"><div class="panel"><div class="form-group " id="get_menu_list"></div></div></div>五、css样式 *{margin: 0;padding: 0;}.add {margin-right: 10px;}.menu_list { margin:0px 20px 40px 20px;position: relative}.menu { height: 25px;}.first_menu {font-weight: bolder; font-size: 20px;margin:30px 15px 0px 15px;}.second_menu { padding: 25px 45px; font-weight: bold; font-size: 16px;}.third_menu { padding: 20px 0px 20px 90px;font-size: 14px;}.fourth_menu{padding: 20px 135px;}input {padding-left: 10px;border: none;margin-right: 30px;}.manual_content { width:450px;}.manual_content::after{content: '';}.manual_content a{float: right;margin-right: 10px;}.manual_content a:active::after{content: '';}.ui-accordion-header{border: none;}.ui-accordion-header.ui-state-active:after{content:""}a{display: inline-block}a:link{text-decoration: none}a:active{text-decoration: none}a:visited{text-decoration: none}a:hover{text-decoration: none}/*.second_menu_list{display: none}*/.is_show{font-size: 30px;}.menu_list{padding-right: 60px;}.btn-del,.btn-add{margin: -30px 10px 0 10px;}.btn-add{position: absolute; right:35%;}.btn-del{position:absolute;right: 30%;}.menu .path_address{font-size: 14px;width:400px;margin-left: 30px;font-weight: normal}六、js//通过ajax,把数据加载到menu_list_page页⾯$.ajax({url : '/system/ajax_get_menu_list_page',type : 'post',async : false,data : {},dataType : 'json',success : function(res){if( res.error == 0){$("#get_menu_list").prepend(res.content);}else{}}});//添加其他⽅法动态实现⽬录的增删改查。
现在到处都有这方面的教程,我重点说一下我自己搞的一个框架。
特点:支持Form的无闪提交(方法有点笨)支持MVC框架,即支持传统网页架构多线程并发请求(要语言支持线程)动态加载文件,只加载有用的!处理了Ajax框架臃肿的JS文件问题。
采用no table的全div + css布局a. 获得XMLHTTPRequest对象,网上到处都找得到了,不多说:function newXMLHttpRequest() {var xmlreq = false;if (window.XMLHttpRequest) {xmlreq = new XMLHttpRequest();} else if (window.ActiveXObject) {try {xmlreq = new ActiveXObject("Msxml2.XMLHTTP");} catch (e1) {try {xmlreq = new ActiveXObject("Microsoft.XMLHTTP");} catch (e2) {}}}return xmlreq;}这里提供一个通用的支持多浏览器的方法。
b.提出异步请求//这里用Bcandy作为方法名是为了感谢一个对我来说很重要的人,她一直在支持我function Bcandy(Tid,url,parm,js) {if(url == ""){return;}//这是一个加载信息提示框,也可以不要!document.getElementById("load").style.visibility = "visible";//加载相应页面的JS文件if(js != null){//加载JS文件LoadJS(js);}// 获取一个XMLHttpRequest实例var req = newXMLHttpRequest();// 设置用来从请求对象接收回调通知的句柄函数var handlerFunction = getReadyStateHandler(req,Tid);req.onreadystatechange = handlerFunction;// 第三个参数表示请求是异步的req.open("POST", url, true);// 指示请求体包含form数据req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");// 发送参数req.send(parm);}function getReadyStateHandler(req,Tid) {// 返回一个监听XMLHttpRequest实例的匿名函数return function () {// 如果请求的状态是“完成”if (req.readyState == 4) {// 成功接收了服务器响应if (req.status == 200) {//下面一句是重点,这里显示了返回信息的内容部分,也可以加以修改。
1.1跟我学AJAX技术——如何应用AJAX实现无刷新查询功能的Web应用示例(第三部分)1.1.1对前面的XML响应加以改进以表格的形式显示输出1、在页面中增加一个parseXMLResponseInTable的JavaScript方法function parseXMLResponseInTable(){var dataArray = httpRequest.responseXML.getElementsByTagName("data"); //<data> var dataArrayLen = dataArray.length;var insertData = "<table style='width:250px; border: solid 1px #000'>"+"<tr><th>XML的处理结果</th></tr>";for (var i=0; i<dataArrayLen; i++){if(dataArray[i].tagName){insertData =insertData+"<tr>";insertData =insertData+"<td>" + dataArray[i].tagName + "</td>";insertData =insertData+"<td>" + dataArray[i].firstChild.data + "</td>";insertData =insertData+"</tr>";}}insertData =insertData+"</table>";//使用HTML标签来更新一个标签元素mdiv = document.getElementById("showResultMessage");mdiv.innerHTML = insertData;}对上面的代码进行说明:(1)"dataArray"作为所有<data>节点的数组(不是节点数据,只是节点)。
多叉树结合JavaScript树形控件实现无限级树形菜单(一种构建多级有序树形结构JSON(或XML)数据源的方法)一、问题研究的背景和意义在Web应用程序开发领域,基于AJAX技术的JavaScript树形控件已经被广泛使用,它用来在Html页面上展现具有层次结构的数据项。
目前市场上常见的JavaScript框架及组件库中均包含自己的树形控件,例如JQuery、Dojo、Yahoo UI、Ext JS等,还有一些独立的树形控件,例如dhtmlxtree等,这些树形控件完美的解决了层次数据的展示问题。
展示离不开数据,树形控件主要利用AJAX技术从服务器端获取数据源,数据源的格式主要包括JSON、XML等,而这些层次数据一般都存储在数据库中。
“无限级树形菜单”,顾名思义,没有级别的限制,它的数据通常来自数据库中的无限级层次数据,这种数据的存储表通常包括id和parentId这两个字段,以此来表示数据之间的层次关系。
现在问题来了,既然树形控件的数据源采用JSON或XML等格式的字符串来组织层次数据,而层次数据又存储在数据库的表中,那么如何建立起树形控件与层次数据之间的关系,换句话说,如何将数据库中的层次数据转换成对应的层次结构的JSON或XML格式的字符串,返回给客户端的JavaScript 树形控件?这就是我们要解决的关键技术问题。
本文将以目前市场上比较火热的Ext JS框架为例,讲述实现无限级树形菜单的方法,该方法同样适用于其它类似的JS树形控件。
Ext JS框架是富客户端开发中出类拔萃的框架之一。
在Ext的UI控件中,树形控件无疑是最为常用的控件之一,它用来实现树形结构的菜单。
TreeNode用来实现静态的树形菜单,AsyncTreeNode用来实现动态的异步加载树形菜单,后者最为常用,它通过接收服务器端返回来的JSON格式的数据,动态生成树形菜单节点。
动态生成树有两种思路:一种是一次性生成全部树节点,另一种是逐级加载树节点(利用AJAX,每次点击节点时查询下一级节点)。
现在到处都有这方面的教程,我重点说一下我自己搞的一个框架。
特点:支持Form的无闪提交(方法有点笨)支持MVC框架,即支持传统网页架构多线程并发请求(要语言支持线程)动态加载文件,只加载有用的!处理了Ajax框架臃肿的JS文件问题。
采用no table的全div + css布局a. 获得XMLHTTPRequest对象,网上到处都找得到了,不多说:function newXMLHttpRequest() {var xmlreq = false;if (window.XMLHttpRequest) {xmlreq = new XMLHttpRequest();} else if (window.ActiveXObject) {try {xmlreq = new ActiveXObject("Msxml2.XMLHTTP");} catch (e1) {try {xmlreq = new ActiveXObject("Microsoft.XMLHTTP");} catch (e2) {}}}return xmlreq;}这里提供一个通用的支持多浏览器的方法。
b.提出异步请求//这里用Bcandy作为方法名是为了感谢一个对我来说很重要的人,她一直在支持我function Bcandy(Tid,url,parm,js) {if(url == ""){return;}//这是一个加载信息提示框,也可以不要!document.getElementById("load").style.visibility = "visible";//加载相应页面的JS文件if(js != null){//加载JS文件LoadJS(js);}// 获取一个XMLHttpRequest实例var req = newXMLHttpRequest();// 设置用来从请求对象接收回调通知的句柄函数var handlerFunction = getReadyStateHandler(req,Tid);req.onreadystatechange = handlerFunction;// 第三个参数表示请求是异步的req.open("POST", url, true);// 指示请求体包含form数据req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");// 发送参数req.send(parm);}function getReadyStateHandler(req,Tid) {// 返回一个监听XMLHttpRequest实例的匿名函数return function () {// 如果请求的状态是“完成”if (req.readyState == 4) {// 成功接收了服务器响应if (req.status == 200) {//下面一句是重点,这里显示了返回信息的内容部分,也可以加以修改。
进行其它处理document.getElementById(Tid).innerHTML = req.responseText;document.getElementById(Tid).style.visibility = "visible";//这一句是实现加载信息提示框的隐藏,也可以不要。
document.getElementById("load").style.visibility = "hidden";} else {// 有HTTP问题发生document.getElementById("load").style.visibility = "hidden";alert("HTTP error: "+req.status);}}}}//动态加载JS文件function LoadJS(file){var head = document.getElementsByTagName('HEAD').item(0);var script = document.createElement('SCRIPT');script.src = file;script.type = "text/javascript";head.appendChild(script);}这就是基本的框架了,因为使用了request.responseText;所以,可以直接请求一个页面jsp,servlet但在使用Struts框架的请求时要进行特殊处理,因为Form不支持异步请求。
建议在这些页面上不要加入标签,就像.net里的asxm文件!而且在使用Struts框架时有点要注意的是,Mapping对象直接返回null就可以了,因为我们会在下面讲到并发多线程。
来处理这个问题的。
总的来看,有点像是积木搭建起来的。
这样方便文件的修改和扩展,互相之间并不影响,而且,实现了代码和标签分离。
在进行传统页面改版时,也不用重新编写全部代码。
只要修改一小部分就可以完美实现Ajax带来的无闪刷新快感。
以上代码均在IE,FireFox下测试过!首先建立一个数据表menumId 菜单主键name 菜单名称url 菜单链接father 低级菜单IDsub 是否最底层菜单(用于判断是否还可以继续展开)target 菜单链接目标(用ajax方式打开时作为显示id) pa 菜单参数(这项用于ajax方式打开菜单)制作一个菜单对象类class Menu{private int mId;private String name;...//其它成员public getMid(){return mId;}public setMid(int mId){this.mId = mId;}....//其它成员的get set方法,}另一个是操作类class MenuOpt(){public Vector getMenus(int father){Vector vector = new Vector();//这里是取得父级菜单ID为father的全部菜单//并封装进Vector的一个对象中。
return vector;}}其次就是一般的jsp文件了。
但要注意以前说过的,不要包含标签!menu.jsp:%@page contentType="text/html; charset=GB2312"%>%@taglib uri="/jsp/jstl/core" prefix="c"%>jsp:useBean id="menu" scope="page" class="ycoe.basic.MenuOpt"/>jsp:setProperty name="menu" property="father" value="${param.father}"/>div>c:forEach var="m" items="${menu.vector}" varStatus = "c">c:choose>c:when test="${m.sub eq 'Y'}">div onClick="showMenu('${m.mid}','${m.url}','${m.target}','father=${m.mid}')"> img src="pic/menu0.gif" id="img${m.mid}" alt="" style=" cursor:hand;">a href="#" class="text1">${}/div>div style="display:none;" id="tr${m.mid}">div style="padding-left:12pt" id="${m.mid}">/div>/c:when>c:otherwise>div onclick="openMenu('${m.url}','${m.target}','${m.pa}');">img src="pic/menu1.gif" id="img${m.mid}" alt="">a href="#" class="text1">${}/div>menu.js://operMenu(打开下拉菜单的ID,打开的地址,链接打开的目标,参数)。
//这是用在menu.jsp的方法function showMenu(id,url,target,param){var trObj = document.getElementById("tr"+id);var tdObj = document.getElementById(id);//try{if(document.getElementById("tr"+id).style.display == "none"){//显示菜单if(tdObj.innerHTML == null || tdObj.innerHTML == ""){//提取数据document.getElementById("tr"+id).style.display = "";document.getElementById("img"+id).src = "pic/menu2.gif"Bcandy(id,"page/menu.jsp",param,"");openMenu(url,target,param);}else{//如果里面有内容,直接显示document.getElementById("tr"+id).style.display = "";document.getElementById("img"+id).src = "pic/menu2.gif"openMenu(url,target,param);}//Bcandy(target,url,param,"");//打开菜单链接}else{//隐藏菜单document.getElementById("tr"+id).style.display = "none";document.getElementById("img"+id).src = "pic/menu0.gif"}//}catch(e){}}//打开菜单function openMenu(url,target,param){//这里不用我写了吧。