Javascript 从HTML大纲创建分层对象

Javascript 从HTML大纲创建分层对象,javascript,jquery,html,dom,recursion,Javascript,Jquery,Html,Dom,Recursion,我最终想要创建一个jQuery插件,它在DOM的顶层循环,并向对象添加元素,直到它到达一个标题,在这一点上它推送一个带有该标题文本的对象 在遇到新标题之前,将向该新对象添加以下同级元素-如果标题处于同一级别,将像以前一样创建一个新对象作为父对象的同级,并将DOM同级添加到该对象,而不是第一个对象;如果标题处于较低级别,则作为第一个对象的子对象添加,同级DOM元素作为子对象添加到该标题对象;如果是更高级别的标题,则在最后一个标题对象的上方添加一个新对象,并继续循环 例如: <p>woo

我最终想要创建一个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>
这是:

var root=$(res)
.filter(“#内容”)
.儿童()
.not('style');//不需要样式表,hurr!
var sections=root.filter('h1');
var大纲={};
对于(变量i=0;i如果(i+1,我将以一个示例开始,该示例将遍历节点并将它们全部添加到同一个
树中

JSBin:


更新 请尝试以下示例:

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);

你可以用键按你喜欢的任何顺序创建对象,但你不能按最初插入的顺序检索对象的键。如果你需要有序的集合,请使用数组。@PaulRoub有没有办法用JavaScript命名数组键?我知道在PHP中你可以创建数组,如
[“something”=>“hurr”,1=>“derpa”]
他们会保持某种秩序,IIRC。如果这是一个愚蠢的问题,我很抱歉,我现在有点过于咖啡因化了。不。JS数组只按数字索引。非数字索引用于对象,并且无序。句号。用示例代码更新了问题。对于那些否决的问题,请包括解释原因的注释。我无法改进如果我没有得到任何反馈,请回答我的问题。谢谢。我遇到的问题并不是向树的顶层添加顶级元素……看看新示例是否有帮助。
    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);
// 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);