HTML(DOM)与JavaScript嵌套数组之间相互转换

html2ja:将html目标元素解析为JavaScript数组字面量,每项的值为tagName,className,id等CSS选择器组合;

showJa:将html2ja生成的数组缩进格式化显示;

walkDOM:遍历DOM目标元素(这个来自老道的the Good Parts)。

ja2html:与html相反的过程

PS:以下代码只是简单的构思测试,实际使用请自行完善。

代码片段:

/*
<html>
<head>
<title>HTML RESTructure</title>
<style>
</style>
<script>
*/
// workDOM函数遍历目标元素或节点
// 有两种模式:
// 1. `element`模式(认)(包含所定义的元素项)
// 2. `node`模式(包含文本节点在内的所有节点)
function walkDOM(mode) {
var m = mode || element;
var f = firstElementChild,
n = nextElementSibling;
if (m === node) {
f = firstChild;
n = nextSibling;
}

return function _(val,func) {
func(val);
val = val[f];
while (val) {
_(val,func);
val = val[n];
}
};
}
// html2ja函数将HTML目标元素转换为JavaScript数组,
// 这个函数调用了eval函数,并且为每一个目标范围
// 内的元素加了一个index属性(这是特意设置的)。
function html2ja(elt) {
var walk = walkDOM(),
lis;
walk(elt,function (el) {
var pe = el.parentElement,
pes = el.prevIoUsElementSibling;

var sel = el.tagName;
if (el.className)
sel += ' .' + el.className;
if (el.id)
sel += ' #' + el.id;

if (el === elt) {
el.index = '0';
lis = [sel];
} else {
if (pes) {
el.rank = pes.rank + 1;
} else {
el.rank = 1;
}
var t = pe.index.split(',').slice(0,-1).concat(el.rank);
el.index = t.concat(0).join(',');
eval('lis[' + t.join('][') + '] = [sel];');
}
});
return lis;
}

window.onload = function () {
var ind = '';
var showJa = function _(o) {
var i,
s = '';
for (i = 0; i < o.length; i++) {
var s1;
if (typeof o[i] === 'object') {
ind += ' ';
s = s.slice(0,-1) + ',' + ind + _(o[i]) + ']';
} else {
s = s.slice(0,-1) + '[' + o[i] + ']';
}
}
ind = ind.slice(0,-1);
return s;
};

document.getElementById(code-pre).innerText = showJa(html2ja(document.documentElement));
};
/*
</script>
</head>
<body>
<div id=header>
<h1 align=center>HTML RESTructure</h1>
<p align=right>[HTML] + [REST] + [JSON] = [HTML RESTructure]</p>
</div>
<div id=main>
<div class=article id=art_1>
<h2>HTML <==> REST</h2>
<p>
<pre>
HTML DOM是一个树形的文档模型,
所以很方便的将其转化为其它数据结构。
这里,我将DOM映射到JSON,具体来说,
是用JavaScript Array字面量表示出来。
而REST也可以JSON的方式保存其状态
及逻辑结构,若是通过JSON架起这座从
HTML到REST(或反过来)的桥梁,数据
结构将会变得异常清晰,内容管理更便
捷。
</pre>
</p>
</div>
<div class=article id=art_2>
<h2>XHTML Core Elements</h2>
<p>
<pre>
通常情况下,有这些就足够了:
1. DIV: 块
2. P: 段落
3. SPAN: 节
4. A: 锚
5. H1-H6: 标题
6. UL & LI: 无序列表
7. PRE: 预格式文本
</pre>
</p>
</div>
<div class=article id=art_3>
<h2>JavaScript Array</h2>
<p>
<pre id=code-pre>
</pre>
</p>
</div>
</div>
<div id=footer>
<p align=center>&copy; <a class=user-name href=mailto: rugby@gmail.com>rugby</a>,2011</p>
</div>
</body>
</html>
*/

代码片段:

/*
<script>
*/
// 将JavaScript嵌套数组转换为HTML DOM结构
// 与上面的html2ja刚好相反
var ja2html = function _(ja,dst) {
var els = ja[0].split(' '),
elt = document.createElement(els[0]);
if (dst.tagName !== els[0]) {
if (els.length > 1) {
if (els.length < 3) {
var sig = els[1].slice(0,1);
if (sig === '.')
elt.className = els[1].slice(1);
else
elt.id = els[1].slice(1);
} else {
elt.className = els[1].slice(1);
elt.id = els[2].slice(1);
}
}
dst.appendChild(elt);
dst = elt;
}
var j = 1;
while (j < ja.length) {
_(ja[j],dst);
j += 1;
}
};

// 测试
var ja = (
[HTML,
[HEAD,
[TITLE],
[STYLE],
[SCRIPT]],
[BODY,
[DIV #header,
[H1],
[P]],
[DIV #main,
[DIV .article #art_1,
[H2],
[P],
[PRE],
[DIV .article #art_2,
[DIV .article #art_3,
[PRE #code-pre],
[P]]],
[DIV #footer,
[P,
[A .user-name]]]]]
);
// alert(ja);
window.onload = function () { ja2html(ja[2],document.body); };
/*
</script>
*/

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...