实现类似微博、QQ空间等的动态加载
微博、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>元素动态加载子元素,因此需要刷新<ul>, 即$('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
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>乘客留言墙</title>
<link rel="shortcut icon" href="../image/wireless_box.ico">
<link rel="stylesheet" href="../jquery.mobile-1.3.0/jquery.mobile-1.3.0.min.css">
<script src="../jquery.mobile-1.3.0/jquery-1.9.1.min.js"></script>
<script src="../jquery.mobile-1.3.0/jquery.mobile-1.3.0.min.js"></script>
<script src="../js/record_user_behavior_1.js"></script>
<style>
#wrap {
white-space:normal;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-align: left;
}
</style>
</head>
<body>
<%
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"); //选择前十条未读的显示
%>
<div data-role="page" data-theme="a">
<div data-role="header" data-position="fixed">
<h1 style="color: white; font-family: Helvetica,Arial,sans-serif; font-weight: bold;">乘客留言</h1>
<a href="index.jsp" data-shadow="false"
data-iconshadow="false" data-icon="arrow-l" data-iconpos="notext"
data-ajax="false">Back</a>
</div>
<div data-role="content">
<ul data-role ="listview" data-inset ="true">
<%
if(re.next()){
if(re.previous()){};
while(re.next()){
descript = re.getString("descrip");
date = re.getString("date");
time = re.getString("time");
%>
<div data-role="button" style="width: 100%; height: auto">
<div id="wrap" style="font-size: 16px;
color: white; width: 100%; height: auto; "><%= descript
%></div>
<br />
<p style="margin-left:-15px;">
<span style="float:left; color:
white; "><strong>发布时间:<%= date %> <%= time
%></strong></span>
</p>
</div>
<%
}
}
%>
</ul>
<div data-role="button" style="width: 100%; height: auto" onclick="loadmore()">
加载更多
</div>
</div>
</div>
<script>
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();
}
</script>
<%
re.close();
stmt.close();
con.close();
%>
</body>
</html>
"message_load.jsp"用于服务器端加载信息及返回
<%--
Document : update_message
Created on : 2013-5-13, 20:08:31
Author : zengyi
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%
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 += "<div align=\"center\" data-role=\"button\" style=\"width: 100%; height: auto\">";
outstring += "<div id=\"wrap\" style=\"font-size:
16px; color: white; width: 100%; height: auto;
\">"+descript+"</div>";
outstring += "<br />";
outstring += "<p style=\"margin-left:-15px;\">";
outstring += "<span style=\"float:left; color: white;
\"><strong>发布时间:"+date+time+"</strong></span><
/p></div>";
}
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){}
}
}
//-------------------------------------------------
%>