微博、QQ空间等的动态加载方式属于滚屏加载技术,获取当前滚动条位置来触发onscroll()函数,向服务器发起请求,将请求得到的新的数据动态加载在页面上
本文利用该原理实现了动态加载,但不是检测当前滚动条位置来触发函数,而是由按钮事件触发,因此更简单一些。
走过的弯路
1) 将目前读取到的数据库中的位置存放在session中,当要加载更多的时候,去session中获得该值,动态加载后修改session中的值
错误原因:session是有缓存的,如果停留在当前页面,得到的值还是一开始的session值,就算在该页面进行了修改
2) 将服务器逻辑控制代码通过内嵌的方式放在网页页面中,即通过的方式嵌入
错误原因:这些代码在一开始加载网页的时候,便在服务器端一次执行过后加载在网页中,不会因为网页的后续事件而触发代码段的重新执行
思路
1) 在数据库中,为表项添加一个属性state,用于表示该项是否已经加载
2) 进入该页面时,先将所有的元素的state置0,表示所有的项目都还没加载;通过选中根据一定排序规则排序后的前n项,并将这n项的state置1,表示已经加载
3) 在后续的操作中,若用户想查看更多,选择“加载更多”,即触发加载事件,向服务器发送ajax请求,服务器取得还没加载的项目根据一定排序规则后的前n项,生成网页代码字符串并返回;最后将这n项的state置1
4)当数据库中所有的项目都已加载,则返回0,以供网页端判断处理
注意
1)
网页端通过append()函数动态加载网页元素,无法加载css等,会显示异常,要加上$('#id').trigger("create");才能加
载成功;另外,我的例子中是在jquery
mobile中实现的,为
- 元素动态加载子元素,因此需要刷新
- ,
即$('ul').listview("refresh");
2) Mysql语言中,选择符合条件的记录m到n,不能直接写select * where condition limit m,n
该句的意思是从m开始的n项记录
以上方式利用数据库实现,在实际应用中,若考虑到多用户,则不用采用上述情况,可以考虑使用cookie来存储当前加载位置或者直接在js中利用变量存储当前位置
源码如下:"user_message.jsp"(用于显示留言页)
Document : staff_info
Created on : 2013-7-22, 9:28:58
Author : zengyi
--%>
乘客留言墙#wrap {
white-space:normal;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-align: left;
}
ResultSet re = null;
Statement stmt = null;
Connection con = null;
String date, descript, time;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String connectionUrl = "jdbc:mysql://localhost/wb?" +
"user=root&password=526156";
con = DriverManager.getConnection(connectionUrl);
stmt = con.createStatement();
} catch (SQLException e) {
System.out.println("SQL Exception: "+ e.toString());
}
re = stmt.executeQuery("SELECT * FROM user_message_other order by id DESC limit 10"); //选择前十条未读的显示
%>
if(re.next()){
if(re.previous()){};
while(re.next()){
descript = re.getString("descrip");
date = re.getString("date");
time = re.getString("time");
%>
%>
发布时间:
%>
}
}
%>
加载更多
var load_pos = 10;
function loadmore(){
var xmlhttp;
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
if(xmlhttp.responseText==0){
alert("已加载完所有留言");
}
else{
load_pos += 10;
$('ul').append(xmlhttp.responseText);
$('ul').trigger("create");
$('ul').listview("refresh");
}
}
}
xmlhttp.open("GET","message_load.jsp?load_pos="+load_pos,false);
xmlhttp.send();
}
re.close();
stmt.close();
con.close();
%>
"message_load.jsp"用于服务器端加载信息及返回
Document : update_message
Created on : 2013-5-13, 20:08:31
Author : zengyi
--%>
ResultSet re = null;
Statement stmt = null;
Connection con = null;
String date, descript, time;
int load_pos_start = Integer.parseInt(request.getParameter("load_pos"));
String outstring = "";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String connectionUrl = "jdbc:mysql://localhost/wb?" +
"user=root&password=526156";
con = DriverManager.getConnection(connectionUrl);
stmt = con.createStatement();
re = stmt.executeQuery("SELECT * FROM user_message_other order
by id DESC limit "+load_pos_start+",10"); //从未读的消息中选择十条显示
if(re.next()){
if(re.previous()){};
while(re.next()){
descript = re.getString("descrip");
date = re.getString("date");
time = re.getString("time");
outstring += "
outstring += "
16px; color: white; width: 100%; height: auto;
\">"+descript+"
outstring += "
";
outstring += "
";
outstring += "
\">发布时间:"+date+time+"
</p>
}
out.print(outstring);
}
else{
out.print(0);
}
} catch (SQLException e) {
System.out.println("SQL Exception: "+ e.toString());
} catch (ClassNotFoundException cE) {
System.out.println("Class Not Found Exception: "+ cE.toString());
}
finally{
if (re !=null){
try{ re.close(); }catch(SQLException sqlEx){}
}
if (stmt !=null){
try{ stmt.close(); }catch(SQLException sqlEx){}
}
if (con !=null){
try{ con.close(); }catch(SQLException sqlEx){}
}
}
//-------------------------------------------------
%>