Ajax-ajax執行個體3-動態樹形列表

來源:互聯網
上載者:User

標籤:win   auto   primary   ini   data   item   table   example   jdb   

項目結構:

 

項目示範:

 

技術要點:

1.3.2 技術要點
在基本原理的介紹中,瞭解到通過在父節點內動態建立子節點,並利用樣式表縮排完成樹形列表
的基本架構。除了這一點外,還有下面一些問題需要考慮。
1 .將父節點所有的子節點放入一個容器中
基本原理頁面中僅包含了建立子節點的功能,不可以將建立好的節點再進行關閉操作。實際應用
中菜單總是包含開啟和關閉兩種操作。為了方便進行關閉操作,將子節點放入一個容器中,在關閉時
只需要設定容器的顯示內容即可。
2 .節點開關的具體實現
每個父節點的所有子節點放入容器中後,在單擊父節點時判斷子節點容器的顯示狀態。如果當前
為開啟狀態,則將其關閉,反之則將其開啟。具體使用的方法是調用節點的 style.display 屬性進行判斷,
關閉時的狀態為 none,非 none 時表示開啟。為了清晰地表示父節點的開啟或關閉狀態,使用“+”和
“-”字元進行標識。
3 .節點分為目錄節點和非目錄節點
目錄節點下可包含子節點,非目錄節點也可稱為葉子節點,即該節點不包含子節點。在本例中對
這兩種節點進行區別對待。單擊目錄節點將對其子節點進行展開或關閉操作。單擊非目錄節點將連結
到新的頁面(目前暫時將新頁面地址彈出,在實際應用中可進行修改)。

 

資料庫:

CREATE TABLE `tree` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主鍵‘,  `text` varchar(255) NOT NULL COMMENT ‘顯示文本‘,  `isfolder` varchar(5) NOT NULL DEFAULT ‘false‘ COMMENT ‘是否含有下級目錄‘,  `link` varchar(255) NOT NULL COMMENT ‘串連‘,  `pid` int(11) NOT NULL DEFAULT ‘0‘ COMMENT ‘父id‘,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8

 

GetTreeByParentId.java:擷取節點資訊servlet:

package com.gordon.servlet;import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;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.util.DBUtils;/** * Servlet implementation class GetTreeByParentId */@WebServlet("/GetTreeByParentId")public class GetTreeByParentId extends HttpServlet {private static final long serialVersionUID = 1L;/** * @see HttpServlet#HttpServlet() */public GetTreeByParentId() {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 {request.setCharacterEncoding("utf-8");response.setContentType("text/xml;charset=utf-8");String parentId = request.getParameter("parentId"); // 擷取要載入的節點編號// 建立用於儲存 xmlTree 資訊的 StringBuffer 對象StringBuffer xmlTree = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");xmlTree.append("<tree>"); // xmlTree 根節點為<tree>/* * 根據請求的目標節點返回不同的結果 isFolder 屬性標識當前節點是否為目錄,true 表示目錄,false 表示普通節點 link * 屬性用於設定普通節點的目標連結地址 */String sql = "select * from tree where pid = ?"; // 定義查詢資料庫的 SQL 陳述式Connection conn = null; // 聲明 Connection 對象PreparedStatement pstmt = null; // 聲明 PreparedStatement 對象ResultSet rs = null; // 聲明 ResultSet 對象try {conn = DBUtils.getConnection(); // 擷取資料庫連接pstmt = conn.prepareStatement(sql); // 建立 PreparedStatementpstmt.setString(1, parentId); // 設定參數rs = pstmt.executeQuery(); // 執行查詢,返回結果集while (rs.next()) { // 遍曆結果集建立 item-節點xmlTree.append("<item id=\"");xmlTree.append(rs.getString("id"));xmlTree.append("\" isFolder=\"");xmlTree.append(rs.getString("isfolder"));String link = rs.getString("link");// 當 link 欄位資料存在時才加入 link 屬性資訊if (link != null && !"".equals(link)) {xmlTree.append("\" link=\"");xmlTree.append(link);}xmlTree.append("\">");xmlTree.append(rs.getString("text"));xmlTree.append("</item>");}} catch (ClassNotFoundException cnfe) {System.out.println(cnfe.toString());} catch (SQLException e) {System.out.println(e.toString());}try {rs.close(); // 關閉結果集pstmt.close(); // 關閉 PreparedStatementconn.close(); // 關閉串連} catch (Exception e) {System.out.println(e.toString());}xmlTree.append("</tree>"); // xmlTree 根節點的結束標籤System.out.println(xmlTree.toString());response.getWriter().print(xmlTree.toString());}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse *      response) */protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

 

DBUtil.java:資料庫連接:

package com.gordon.util;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class DBUtils {private static final String URL = "jdbc:mysql://localhost:3306/ajaxexample_3";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);}}

 

tree.css:

/* 子節點容器 box 需要縮排 */div.box {margin-left: 20px;}/* 目錄節點標識樣式 */span.folderMark {font-family: "宋體";color: #F00;cursor: hand;margin-right: 5px;}/* 目錄節點樣式 */span.folder {cursor: hand;}/* 非目錄節點標識樣式 */span.itemMark {font-family: "宋體";color: #F00;margin-right: 5px;}/* 非目錄節點樣式 */span.item {cursor: hand;}

 

tree.js:

// 建立Tree對象var Tree = new function() {this._url = "GetTreeByParentId"; // 用於請求資料的伺服器頁面地址this._openMark = "-"; // 目錄節點處於展開狀態時的標識this._closeMark = "+"; // 目錄節點處於關閉狀態時的標識this._itemMark = "·"; // 非目錄節點標識this._initId = "treeInit"; // 樹形目錄初始 div 標識this._rootData = "根目錄"; // 根節點文字資訊this._boxSuffix = "_childrenBox"; // 子節點容器尾碼this._folderType = "folder"; // 目錄節點類型變數this._itemType = "item"; // 非目錄節點類型變數// 初始化根節點this.init = function() {var initNode = document.getElementById(this._initId); // 擷取初始 divvar _node = document.createElement("div"); // 建立新 div 作為根節點_node.id = "0"; // 根節點 id 為 0_node.innerHTML = this.createItemHTML(_node.id, this._folderType,this._rootData);initNode.appendChild(_node); // 將根節點加入初始 div}// 擷取給定節點的子節點this.getChildren = function(_parentId) {// 擷取頁面子節點容器 boxvar childBox = document.getElementById(_parentId + this._boxSuffix);// 如果子節點容器已存在,則直接設定顯示狀態,否則從伺服器擷取子節點資訊if (childBox) {var isHidden = (childBox.style.display == "none"); // 判斷目前狀態是否隱藏// 隱藏則顯示,如果顯示則變為隱藏childBox.style.display = isHidden ? "" : "none";// 根據子節點的顯示狀態修改父節點標識var _parentNode = document.getElementById(_parentId);_parentNode.firstChild.innerHTML = isHidden ? this._openMark: this._closeMark;} else {var xmlHttp = this.createXmlHttp(); // 建立 XmlHttpRequest 對象xmlHttp.onreadystatechange = function() {if (xmlHttp.readyState == 4) {// 調用 addChildren 函數產生子節點Tree.addChildren(_parentId, xmlHttp.responseXML);}}xmlHttp.open("GET", this._url + "?parentId=" + _parentId, true);xmlHttp.send(null);}}// 根據擷取的 xmlTree 資訊,設定指定節點的子節點this.addChildren = function(_parentId, _data) {var _parentNode = document.getElementById(_parentId); // 擷取父節點_parentNode.firstChild.innerHTML = this._openMark;// 設定節點前標記為目錄展開形式// 建立一個容器,稱為 box,用於存放所有子節點var _nodeBox = document.createElement("div");// 容器的 id 規則為:在父節點 id 後加固定尾碼_nodeBox.id = _parentId + this._boxSuffix;_nodeBox.className = "box"; // 樣式名稱為 box,div.box 樣式會對此節點生效_parentNode.appendChild(_nodeBox); // 將子節點 box 放入父節點中// 擷取所有 item-節點var _children = _data.getElementsByTagName("tree")[0].childNodes;var _child = null; // 聲明_child 變數用於儲存每個子節點var _childType = null; // 聲明_childType 變數用於儲存每個子節點類型for (var i = 0; i < _children.length; i++) { // 迴圈建立每個子節點_child = _children[i];_node = document.createElement("div"); // 每個節點對應一個新 div_node.id = _child.getAttribute("id"); // 節點的 id 值就是擷取資料中的 id 屬性值// 設定子節點類型_childType = _child.getAttribute("isFolder") == "true" ? this._folderType: this._itemType;// 根據節點類型不同,調用 createItemHTML 建立節點內容if (_childType == this._itemType) {// 非目錄節點在最後多傳一個 link 資料,用於單擊後連結到新頁面_node.innerHTML = this.createItemHTML(_node.id, _childType,_child.firstChild.data, _child.getAttribute("link"));} else {// 目錄節點只需傳遞 id,節點類型,節點資料_node.innerHTML = this.createItemHTML(_node.id, _childType,_child.firstChild.data);}_nodeBox.appendChild(_node); // 將建立好的節點加入子節點 box 中}}// 建立節點的頁面片斷this.createItemHTML = function(itemId, itemType, itemData, itemLink) {// 根據節點類型不同,返回不同的 HTML 片斷if (itemType == this._itemType) {// 非目錄節點的 class 屬性以 item 開頭,並且 onclick 事件調用 Tree.clickItem 函數return ‘<span class="itemMark">‘ + this._itemMark + ‘</span>‘+ ‘<span class="item" onclick="Tree.clickItem(\‘‘+ itemLink + ‘\‘);">‘ + itemData + ‘</span>‘;} else if (itemType == this._folderType) {// 目錄節點的 class 屬性以 folder 開頭,並且 onclick 事件調用 Tree.getChildren 函數return ‘<span class="folderMark" onclick="Tree.getChildren(\‘‘+ itemId + ‘\‘)">‘ + this._closeMark + ‘</span>‘+ ‘<span class="folder" onclick="Tree.getChildren(\‘‘+ itemId + ‘\‘)">‘ + itemData + ‘</span>‘}}// 單擊葉子節點後的動作,目前只是彈出對話方塊,可修改為連結到具體的頁面this.clickItem = function(_link) {alert("當前節點可以連結到頁面 " + _link + " 。");}// 用於建立 XMLHttpRequest 對象this.createXmlHttp = function() {var xmlHttp = null;// 根據 window.XMLHttpRequest 對象是否存在使用不同的建立方式if (window.XMLHttpRequest) {xmlHttp = new XMLHttpRequest(); // FireFox、Opera 等瀏覽器支援的建立方式} else {xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // IE 瀏覽器支援的建立方式}return xmlHttp;}}

 

index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><title>動態樹形列表</title><script type="text/javascript" src="js/tree.js"></script><link href="css/tree.css" type="text/css" rel="stylesheet"></head><body onload="Tree.init()"><h1>動態樹形列表</h1><div id="treeInit"></div></body></html>

 

Ajax-ajax執行個體3-動態樹形列表

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.