我最终想要创建一个jQuery插件,该插件在DOM的顶层循环,并向对象添加元素,直到它到达一个标题,这时它会推送带有该标题文本的对象。
以下同级元素将被添加到这个新对象中,直到遇到新的标题——如果标题在同一级别,则会像以前一样创建一个新对象作为父对象的同级,并将DOM同级添加到该对象中,而不是第一个对象;如果标题在较低级别,则将其作为第一个对象的子对象添加,并且将兄弟DOM元素作为子对象添加到该标题对象;如果是更高级别的标题,则会在最后一个标题对象的上一级添加一个新对象,并继续循环。
示例:
<p>wooo</p>
<h1>stuff</h1>
<p>stuff</p>
<p>more stuff</p>
<h2>yet more stuff</h2>
<p>still more stuff</p>
<h3>even still more stuff</h3>
<p>yep — stuff!</p>
<h1>still yet more stuff</h1>
<p>stuff stuff stuff</p>
<p>stuff stuff stuffarino</p>
成为。。。
{
'p_wooo': HTMLElementObject,
'h1_stuff': {
'p_stuff': HTMLElementObject,
'p_more_stuff': HTMLElementObject,
'h2_yet_more_stuff': {
'p_still_more_stuff': HTMLElementObject,
'h3_even_still_more_stuff': {
'p_yep_stuff': HTMLElementObject,
}
},
},
'h1_still_yet_more_stuff': {
'p_stuff_stuff_stuff': HTMLElementObject,
'p_stuff_stuff_stuffarino': HTMLElementObject
{
}
到目前为止,我拥有的是:
var root = $(res)
.filter('#contents')
.children()
.not('style'); // Don't need no stylesheets hurr!
var sections = root.filter('h1');
var outline = {};
for (var i = 0; i < sections.length; i++) {
var children;
if (i+1 <= sections.length) {
children = root.filter(sections[i]).after().nextUntil(sections[i+1]).filter(function(){return $(this).text().trim() !== '';});
}
var slug = getSlug($(sections[i]).text(), {separator: '_'});
outline[slug] = children;
}
console.dir(outline);
唉,它只适用于H1如何将其转化为添加H2-H6s的递归函数
我将从一个遍历节点并将它们全部添加到同一个tree
对象中的示例开始。从这里可以很容易地计算出其余部分:
JSBin:http://jsbin.com/bixekutuhe/1/edit?html,js,输出
// Helpers
function isNode(el) { return el && el.nodeType === 1; }
function tag(el) { return el.tagName.toLowerCase(); }
var tree = {}, key;
var node = document.body.firstElementChild;
while (isNode(node) && tag(node) !== 'script') { // add blacklists or whitelists that you might need
key = node.textContent;
tree[node.tagName.toLowerCase() + '_' +key.split(' ').join('_')] = node;
node = node.nextElementSibling; // move to next element
}
console.log(tree);
更新
请尝试以下示例:
var tree = {};
var currentTree = tree, tagName, key;
var node = document.body.firstElementChild;
function isNode(el) { return el && el.nodeType === 1; }
function tag(el) { return el.tagName.toLowerCase(); }
while (isNode(node)) {
tagName = tag(node);
key = tagName + '_' + node.textContent.trim().split(' ').join('_');
switch(tagName) {
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
if (tagName === 'h1') {
currentTree = tree[key] = {};
} else {
currentTree = currentTree[key] = {};
}
break;
default:
currentTree[key] = node;
break;
}
// Move to the next element
node = node.nextElementSibling;
}
console.log(tree);