jQuery - 解析DOM并创建树结构(复合模式)

时间:2015-03-17 15:05:04

标签: javascript jquery composite

我正在解析DOM,我想 提取与某个选择器匹配的所有元素的层次结构 ,让我们说$('[data-node]')成一个JavaScript对象树结构。我没有找到标准的jQuery方法。使用jQuery.find()似乎返回一个平面列表。也许我错过了一些明显的东西?

例如,我想解析一下:

<div data-node="root">
   <div class="insignificant-presentation">
        <div>
            <div data-node="interestingItem">
            </div>
        </div>
    <div>
    <div data-node="anotherInterestingItem">
        <div data-node="usefulItem">
        </div>
    </div>
</div>

用JavaScript创建一个结构:

[
  {
    "node": "root",
    "children": [
      {
        "node": "interestingItem",
        "children": []
      },
      {
        "node": "anotherInterestingItem",
        "children": [
          {
            "node": "usefulItem",
            "children": []
          }
        ]
      }
    ]
  }
]

2 个答案:

答案 0 :(得分:5)

不确定为什么你需要这个,但是这样的事情应该这样做

$.fn.tree = function() {
    var arr  = [],
        self = this;

    (function runForrestRun(el, arr) {
        var isEl = self.is(el),
            children = [];

        if (isEl)
            arr.push({
                "node" : el.data('node'), 
                "children": children
            });

        el.children().each(function() {
            runForrestRun($(this), isEl ? children : arr);
        });

    }(this.first(), arr));

    return arr;
}

FIDDLE

答案 1 :(得分:1)

function createTree(root) {
  var children = [];

  root.find('div[data-node]').each(function() {
    // I can't think of a better way to not match the same ellement twice. 
    if (!$(this).data('tagged')) {
      $(this).data('tagged', true);
      children.push(createTree($(this)));
    }
  });

  return {
    "node": root.data('node'),
    "children": children
  };
}

var tree = createTree($('div[data-node]').first());

document.write('<pre>' + JSON.stringify([tree], 0, 2))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div data-node="root">
  <div class="insignificant-presentation">
    <div>
      <div data-node="interestingItem">
      </div>
    </div>
    <div>
      <div data-node="anotherInterestingItem">
        <div data-node="usefulItem">
        </div>
      </div>
    </div>
  </div>
</div>