动态加载 FAQ 的过程主要是利用 XMLHttpRequest(以下简称 XHR)对象与服务端通信,根据用户单击的感兴趣问题动态将内容加载到页面中。在具体实现时,有两点要注意的内容。
1 .对每个问题进行唯一标识
FAQ 主要包含问题与解答两个部分,用户单击一个问题时,服务器必须知道请求的是哪个问题的解答,所以必须对每个问题进行唯一标识。标识的方法很多,在本例中简单使用数字进行标识。每个问题在页面上表现为超链接,单击链接将触发 onclick 事件,调用 loadFAQ 函数,传入问题标识,获取对应的解答。单击后并不是要真正链接到一个新的页面,所以在<a>标签的 onclick 事件中 return false 取消原有链接的功能。每个答案分配一个 div 用于显示,每个 div 的 id 属性命名规则为,在对应的问题数字标识前统一增加“faqDetail”。2 .对已加载的解答不重复向服务器发出请求问题的解答加载后,将显示在对应问题下方的 div 中。当用户再次单击问题时该 div 将隐藏起来。如果用户第三次单击相同的问题,由于解答已加载到页面,所以不需要再次向服务器发送请求,只需将隐藏的 div 显示出来即可。隐藏和显示主要通过设置 div 样式中的 display 属性来完成,当 display 属性设置为“none”时隐藏,设置为“block”时显示。判断是否需要发出请求,可以检查 div 的 innerHTML 是否包含内容。项目结构:
项目运行:
数据库:
/*SQLyog Ultimate v12.09 (64 bit)MySQL - 5.5.53 : Database - ajaxexample_1**********************************************************************//*!40101 SET NAMES utf8 */;/*!40101 SET SQL_MODE=''*/;/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;CREATE DATABASE /*!32312 IF NOT EXISTS*/`ajaxexample_1` /*!40100 DEFAULT CHARACTER SET utf8 */;USE `ajaxexample_1`;/*Table structure for table `faqdetail` */DROP TABLE IF EXISTS `faqdetail`;CREATE TABLE `faqdetail` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `answer` varchar(200) NOT NULL COMMENT '问题', `question` varchar(800) NOT NULL COMMENT '答案', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;/*Data for the table `faqdetail` */insert into `faqdetail`(`id`,`answer`,`question`) values (1,'问题1','答案1答案1答案1答案1答案1答案1'),(2,'问题2','答案2答案2答案2答案2答案2答案2');/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
AjaxRequest.js:Ajax封装类:
showfaq.jsp:用于显示faq问题:
<%@page import="java.sql.ResultSet"%><%@page import="java.sql.PreparedStatement"%><%@page import="java.sql.Connection"%><%@page import="com.gordon.util.DBUtil"%><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here <% Connection conn = DBUtil.getConnection(); String sql = "SELECT * FROM faqdetail;"; PreparedStatement pst = conn.prepareStatement(sql); ResultSet rs = pst.executeQuery(sql); while (rs.next()) { %> );return false;"><%=rs.getString("answer")%>" style="display: none;">
<% } rs.close(); pst.close(); conn.close(); %>
GetFaqDetailServlet.java:用于逻辑处理:
package com.gordon.servlet;import java.io.IOException;import javax.servlet.Servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.gordon.service.GetAnswerDetailService;/** * 获取FAQ问题详情 */@WebServlet(urlPatterns = { "/GetFaqDetailServlet" })public class GetFaqDetailServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public GetFaqDetailServlet() { super(); // TODO Auto-generated constructor stub } /** * @see Servlet#init(ServletConfig) */ public void init(ServletConfig config) throws ServletException { // TODO Auto-generated method stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String question = ""; request.setCharacterEncoding("UTF-8"); response.setContentType("text/text;charset=utf-8;"); String answerid = request.getParameter("answerid"); try { question = GetAnswerDetailService.getAnswerDetailById(answerid); } catch (Exception e) { System.out.println(e.getMessage()); } response.getWriter().print(question); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); }}
GetAnswerDetailService.java:用于根据id获取答案的详细代码结构:
package com.gordon.service;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import com.gordon.util.DBUtil;public class GetAnswerDetailService { /** * 根据问题id获取解答信息 * @param answerid * @return * @throws ClassNotFoundException * @throws SQLException */ public static String getAnswerDetailById(String answerid) throws ClassNotFoundException, SQLException { String result = ""; Connection conn = DBUtil.getConnection(); String sql = "SELECT question FROM faqdetail WHERE id = ?"; PreparedStatement pst = conn.prepareStatement(sql); pst.setInt(1, Integer.valueOf(answerid)); ResultSet rs = pst.executeQuery(); while (rs.next()) { result = rs.getString("question"); } rs.close(); pst.close(); conn.close(); return result; }}
DBUtil.java用于获取数据库连接:
package com.gordon.util;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class DBUtil { private static final String URL = "jdbc:mysql://localhost:3306/ajaxexample_1"; private static final String DRIVER = "com.mysql.jdbc.Driver"; private static final String USERNAME = "root"; private static final String PASSWORD = "root"; public static Connection getConnection() throws ClassNotFoundException, SQLException { Class.forName(DRIVER); return DriverManager.getConnection(URL, USERNAME, PASSWORD); }}
+++++++++++++++++++++++++++
参考:ajax实用案例大全-1动态加载数据