基于HTML5树组件延迟加载技术实现

时间:2023-01-13 17:06:14

HT for WebHTML5树组件有延迟加载的功能,这个功能对于那些需要从服务器读取具有层级依赖关系数据时非常有用,需要获取数据的时候再向服务器发起请求,这样可减轻服务器压力,同时也减少了浏览器的等待时间,让页面的加载更加流畅,增强用户体验。

http://www.hightopo.com/guide/readme.html

进入正题,今天用来做演示的Demo是,客户端请求服务器读取系统文件目录结构,通过HT for WebHTML5树组件显示系统文件目录结构。

首先,我们先来设计下服务器,这次Demo的服务器采用Node.js,用到了Node.js的expresssocket.io、fs和http这四个模块,Node.js的相关知识,我在这里就不阐述了,网上的教材一堆,这里推荐下socket.io的相关入门http://socket.io/get-started/chat/

服务端代码代码:

var fs = require('fs'),
express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io')(server),
root = ‘/Users/admin/Projects/ht-for-web/guide‘; io.on('connection', function(socket){
socket.on('explore', function(url){
socket.emit('file', walk(url || root));
});
}); app.use(express.static('/Users/admin/Projects/ht-for-web')); server.listen(5000, function(){
console.log('server is listening at port 5000');
});

io监听了connection事件,并获得一个socket;socket再监听一个叫explore的自定义事件,通过url参数获取到数据后,派发一个叫file的自定义事件,供客户端监听并做相应处理;通过app.use结合express.static设置项目路径;最后让server监听5000端口。

到此,一个简单的服务器就搭建好了,现在可以通过http://localhost:5000来访问服务器了。等等,好像缺了点什么。对了,获取系统文件目录结构的方法忘记给了,OK,那么我们就先来看看获取整站文件的代码是怎么写的:

function walk(pa) {
var dirList = fs.readdirSync(pa),
key = pa.substring(pa.lastIndexOf('/') + 1),
obj = {
name: key,
path: pa,
children: [],
files: []
};
dirList.forEach(function(item) {
var stats = fs.statSync(pa + '/' + item);
if (stats.isDirectory()) {
obj.children.push(walk(pa + '/' + item));
}
else {
obj.files.push({name: item, dir: pa + '/' + item});
}
}); return obj;
}

如大家所见,采用递归的方式,逐层遍历子目录,代码也没什么高深的地方,相信大家都看得懂。那我们来看看运行效果吧:

基于HTML5树组件延迟加载技术实现

duang~文件目录结构出来了,是不是感觉酷酷的,这代码量不小吧。其实,代码并不多,贴出来大家瞅瞅:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>tree-loader</title>
<script src="/socket.io/socket.io.js"></script>
<script src="/lib/core/ht.js"></script>
<script>
var socket = io(), idMap = {};
function init() {
var dm = window.dm = new ht.DataModel(),
tree = new ht.widget.TreeView(dm); tree.addToDOM(); socket.on('file', function(data) {
var root = dm.getDataById(idMap[data.path]);
createChildren(data.children || [], root, dm);
createFiles(data.files || [], root, dm);
});
socket.emit('explore');
} function createChildren(children, parent, dm) {
children.forEach(function(child) {
var n = createData(child, parent);
dm.add(n);
createChildren(child.children || [], n, dm);
createFiles(child.files || [], n, dm);
});
} function createFiles(files, parent, dm){
files.forEach(function(file){
var n = createData(file, parent);
dm.add(n);
});
} function createData(data, parent){
var n = new ht.Data();
n.setName(data.name);
n.setParent(parent);
n.a('path', data.path);
idMap[data.path] = n.getId();
return n;
}
</script>
</head>
<body onload="init();">
</body>
</html>

这就是全部的HTML代码,加上空行总共也就50几行,怎么样,有没有感觉HT for Web很强大。废话不多说,来看看这些代码都干了些什么:

  • 要用到socket.io就需要在页面引入<script src=“/socket.io/socket.io.js”></script>,其实在我的项目中并不存在/socket.io/socket.io.js文件,但是却能正常使用,具体什么原因,我就不多说,大家自己研究去吧;
  • 最重要的是要引入HT for Web的核心包<script src=“/lib/core/ht.js”></script>,这个包不引入的话,下面的HT for Web组件就无法使用;
  • 接下来就是代码了,首先创建一个数据容器DataModel,用来存放文件目录的节点数据,再创建一个TreeView对象并引用刚创建到数据容器,接下来通过socket监听file事件,获取服务器返回的数据,在回调函数中通过调用createChildren和createFiles函数,创建文件目录节点对象,并添加到数据容器中,最后是向服务器发起数据请求,即通过socket派发explore事件。

整体的思路是这样子的,当然这离我们要实现的树组件的延迟加载技术还有些差距,那么,HT for WebHTML5树组件的延迟加载技术是怎么实现的呢?不要着急,马上开始探讨。

首先我们需要改造下获取文件目录的方法walk,因为前面介绍的方法中,使用的是加载整站文件目录,所以我们要将walk方法改造成只获取一级目录结构,改造起来很简单,就是将递归部分改造成获取当前节点就可以了,具体代码如下:

obj.children.push(walk(pa + '/' + item));
// 将上面对代码改成下面的代码
obj.children.push({name: item, path: pa + '/' + item});

这样子服务器就只请求当前请求路径下的第一级文件目录结构。接下来就是要调整下客户端代码了,首先需要给tree设置上loader:

tree.setLoader({
load: function(data) {
socket.emit('explore', data.a('path'));
data.a('loaded', true);
},
isLoaded: function(data) {
return data.a('loaded');
}
});

loader包含了两个方法,load和isLoaded,这两个方法的功能分别是加载数据和判断数据是否已经加载,在load方法中,对socket派发explore事件,当前节点的path为参数,向服务器请求数据,之后将当前节点的loaded属性设置为true;在isLoaded方法中,返回当前节点的loaded属性,如果返回为true,那么tree将不会在执行load方法向服务器请求数据。

接下来需要移除createChildren的两个回调方法,并且在createFiles方法中为创建出来的节点的loaded属性设置成true,这样在不是目录的节点前就不会有展开的图标。createChildren和createFiles两个方法修改后的代码如下:

function createChildren(children, parent, dm) {
children.forEach(function(child) {
var n = createData(child, parent);
dm.add(n);
});
} function createFiles(files, parent, dm){
files.forEach(function(file){
var n = createData(file, parent);
n.a('loaded', true);
dm.add(n);
});
}

如此,HT for Web的HTML5树组件延迟加载技术就设计完成了,我在服务器的控制台打印出请求路径,看看这个延迟加载是不是真的,如下图:

基于HTML5树组件延迟加载技术实现

基于HTML5树组件延迟加载技术实现

看吧,控制台打印的是4条记录,第一条是请求跟目录时打印的,我在浏览器中展开里三个目录,在控制台打印了其对应的目录路径。

等等,现在这个目录看起来好烦,只有文字,除了位子前的展开图标可以用来区别文件和目录外,没有其他什么区别,所以我决定对其进行一番改造,让每一级目录都有图标,而且不同文件对应不同的图标,来看看效果吧:

基于HTML5树组件延迟加载技术实现

怎么样,是不是一眼就能看出是什么文件,这个都是样式上面的问题,我就不再一一阐述了,直接上代码:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="/socket.io/socket.io.js"></script>
<script src="/build/ht-debug.js"></script>
<script>
var socket = io(), idMap = {};
function init() {
var icons = ['css', 'dir-open', 'dir', 'file', 'flash', 'gif', 'html', 'jar',
'java', 'mp3', 'pdf', 'png', 'script', 'txt', 'video', 'xml', 'zip'];
icons.forEach(function(c){
ht.Default.setImage(c, 16, 16, '/test/wyl/images/' + c + '.png');
}); var dm = window.dm = new ht.DataModel(),
tree = new ht.widget.TreeView(dm);
tree.setLoader({
load: function(data) {
socket.emit('explore', data.a('path'));
data.a('loaded', true);
},
isLoaded: function(data) {
return data.a('loaded');
}
});
tree.getLabelFont = function(data){
return '13px Helvetica, Arial, sans-serif';
};
tree.getLabelColor = function (data) {
return this.isSelected(data) ? 'white' : 'black';
};
tree.getSelectBackground = function (data) {
return '#408EDB';
};
tree.getIcon = function (data) {
var icon = data.getIcon() || 'file';
if (data.a('isdir')) {
if (this.isExpanded(data)) {
icon = 'dir-open';
} else {
icon = 'dir';
}
}
return icon;
};
tree.addToDOM(); socket.on('file', function(data) {
var root = dm.getDataById(idMap[data.path]);
createChildren(data.children || [], root, dm);
createFiles(data.files || [], root, dm);
});
socket.emit('explore');
} function createChildren(children, parent, dm) {
children.forEach(function(child) {
var n = createData(child, parent);
n.a('isdir', true);
dm.add(n);
});
} function createFiles(files, parent, dm){
files.forEach(function(file){
var n = createData(file, parent);
n.a('loaded', true);
dm.add(n);
});
} function createData(data, parent){
var name = data.name,
icon = 'file';
if (/.jar$/.test(name)) icon = 'jar';
else if (/.css$/.test(name)) icon = 'css';
else if (/.gif$/.test(name)) icon = 'gif';
else if (/.png$/.test(name)) icon = 'png';
else if (/.js$/.test(name)) icon = 'script';
else if (/.html$/.test(name)) icon = 'html';
else if (/.zip$/.test(name)) icon = 'zip';
var n = new ht.Data();
n.setName(data.name);
n.setParent(parent);
n.setIcon(icon);
n.a('path', data.path);
idMap[data.path] = n.getId();
return n;
}
</script>
</head>
<body onload="init();">
</body>
</html>

在最后,附上完整的服务器代码:

var fs = require('fs'),
express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io')(server),
root = '/Users/admin/Projects/ht-for-web/guide'; io.on('connection', function(socket){
socket.on('explore', function(url){
socket.emit('file', walk(url || root));
});
}); app.use(express.static('/Users/admin/Projects/ht-for-web')); server.listen(5000, function(){
console.log('server is listening at port 5000');
}); function walk(pa) {
var dirList = fs.readdirSync(pa),
key = pa.substring(pa.lastIndexOf('/') + 1),
obj = {
name: key,
path: pa,
children: [],
files: []
};
dirList.forEach(function(item) {
var stats = fs.statSync(pa + '/' + item);
if (stats.isDirectory()) {
obj.children.push({name: item, path: pa + '/' + item});
}
else {
obj.files.push({name: item, dir: pa + '/' + item});
}
}); return obj;
}

http://www.hightopo.com/guide/readme.html

基于HTML5树组件延迟加载技术实现的更多相关文章

  1. HT for Web的HTML5树组件延迟加载技术实现

    HT for Web的HTML5树组件有延迟加载的功能,这个功能对于那些需要从服务器读取具有层级依赖关系数据时非常有用,需要获取数据的时候再向服务器发起请求,这样可减轻服务器压力,同时也减少了浏览器的 ...

  2. 基于 HTML5 的人脸识别技术

    基于 HTML5 的人脸识别技术 https://github.com/auduno/headtrackr/

  3. 基于 HTML5 WebGL 和 VR 技术的 3D 机房数据中心可视化

    前言 在 3D 机房数据中心可视化应用中,随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的 ...

  4. 基于HTML5技术的电力3D监控应用(三)

    继(一)和(二)之后不少,不少网友问我移动终端的使用问题,因为我们项目这次采用Android平板终端,所以我对这方面有点肤浅的研究,这篇分享些项目经验总结,希望对大家有所帮助. 电力3D项目去年底刚立 ...

  5. 基于HTML5技术的电力3D监控应用(一)

    最近参与了国网计量中心的四线一库自动化检定系统的项目开发,团队封闭开发了大半年终于快到尾声了,整个项目过程实在非常累,我的mentor杨杨老师是这样描述的:累的不想说话了.我估计是我太渴望新知识,整天 ...

  6. 基于HTML5技术的电力3D监控应用(二)

    上篇介绍了我们电力项目的基本情况,我们选用HTML5技术还是顶着很大压力,毕竟HTML5技术性能行不行,浏览器兼容性会不会有问题,这些在项目选型阶段还是充满疑惑,项目做到现在终于快收尾了我们才敢松口气 ...

  7. 基于 HTML5 的 WebGL 和 VR 技术的 3D 机房数据中心可视化

    前言 在 3D 机房数据中心可视化应用中,随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的 ...

  8. jmGraph:一个基于html5的简单画图组件

    jmGraph:一个基于html5的简单画图组件 特性: 代码书写简单易理解 面向对象的代码结构 对图形控件化 样式抽离 模块化:入seajs实现模块化开发 兼容性:暂只推荐支持html5的浏览器:i ...

  9. 快速开发基于 HTML5 网络拓扑图应用

    采用 HT 开发网络拓扑图非常容易,例如<入门手册>的第一个小例子麻雀虽小五脏俱全:http://www.hightopo.com/guide/guide/core/beginners/e ...

随机推荐

  1. ASP&period;NET Core中间件&lpar;Middleware&rpar;实现WCF SOAP服务端解析

    ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...

  2. NoSQL生态系统——一致性RWN协议,向量时钟,gossip协议监测故障

    13.5 一致性 在NoSQL中,通常有两个层次的一致性:第一种是强一致性,既集群中的所有机器状态同步保持一致.第二种是最终一致性,既可以允许短暂的数据不一致,但数据最终会保持一致.我们先来讲一下,在 ...

  3. &lbrack;大牛翻译系列&rsqb;Hadoop(2)MapReduce 连接:复制连接(Replication join)

    4.1.2 复制连接(Replication join) 复制连接是map端的连接.复制连接得名于它的具体实现:连接中最小的数据集将会被复制到所有的map主机节点.复制连接有一个假设前提:在被连接的数 ...

  4. &lowbar;&lowbar;construct&lpar;&rpar;和&lowbar;&lowbar;initialize&lpar;&rpar;

    ThinkPHP中的__initialize()和类的构造函数__construct()网上有很多关于__initialize()的说法和用法,总感觉不对头,所以自己测试了一下.将结果和大家分享.不对 ...

  5. groovy install&comma;gvm&comma;groovysh简述(转)

    1.1 安装Groovy Groovy主页:http://www.groovy-lang.org 确保本地系统安装了Java 1.1.1 在Windows系统上安装Groovy 1.创建环境变量GRO ...

  6. EntityFramework Core是否可以映射私有属性呢?了解一下。

    前言 最近几天身体有点抱恙,说话都需要勇气,痛哭.今天简短的写一点探索性的内容,仅供了解,感谢您的阅读. EF Core映射私有属性 在EF 6.x系列中写过一篇文章可以映射私有属性,说明EF的灵活性 ...

  7. Jmeter3&period;2源码编译环境搭建

    1.下载jmeter3.2源码 https://github.com/apache/jmeter/tree/v3_2 https://blog.csdn.net/fly_to_higher/artic ...

  8. 关于MDN,HTML入门来自MDN文档

    由开发者和作者组成的开源社区:推动web发展, MDN(Mozilla Developer Network) 维基,共同维护做贡献: 需要使用到github账号进行验证,以此再创建MDN账号: HTM ...

  9. SpringMVC&lpar;十四&rpar; RequestMapping ModelAndView

    ModelAndView返回模型数据和视图.参考以下Demo代码,了解其实现方法.关注通过视图名称创建ModelAndView的构造方法,以及通过${requestScope.attribute}的方 ...

  10. ubuntu数据库安装配置

    感谢原作者 http://www.linuxidc.com/Linux/2016-12/138081.htm