查找元素组并使用Javascript将它们嵌套在新元素中

时间:2012-03-07 00:58:16

标签: javascript

我刚刚开始使用Javascript,并且正在努力找到一种方法:

  1. 查找相同类型的一个或多个连续元素,例如<p>…</p><p>…</p><p>…</p>
  2. 使用新元素围绕每个组,例如<dd><p>…</p></dd><dd><p>…</p><p>…</p></dd>
  3. 我还想限制脚本,使其仅适用于页面的特定部分,例如: <div id="relevantbit"></div>,但也许这是一个单独的问题。

    提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

这是一个原生的javascript函数,它将连续标记包装在你希望它包含的任何类型的标记中的同一级别。它甚至可以递归地工作,因此它可以在任何级别找到它们。如上所述,当检测连续标记时,它会忽略非元素,如文本节点或注释节点,但如果不是所需的行为(未指定详细信息),则可以轻松修改它。

您可以在此处查看有效的演示:http://jsfiddle.net/jfriend00/Bp97p/

这是代码:

function wrapConsecutive(parent, desiredTagName, wrapTag) {

    desiredTagName = desiredTagName.toUpperCase();
    if (typeof parent === "string") {
        parent = document.getElementById(parent);
    }

    function wrapNodes(nodeBegin, nodeEnd) {
        // create and insert the wrap node
        var wrapNode = document.createElement(wrapTag);
        nodeBegin.parentNode.insertBefore(wrapNode, nodeBegin);
        // now move the matched nodes into the wrap node
        var node = nodeBegin, next;
        while (node) {
            next = node.nextSibling;
            wrapNode.appendChild(node);
            if (node === nodeEnd) {
                break;
            }
            node = next;
        }
    }

    function wrapChildren(parent) {
        var next = parent.firstChild;
        var firstInSeries = null;
        var lastInSeries;
        while (next) {
            // only look at element nodes
            if (next.nodeType === 1) {
                wrapChildren(next);
                if (next.tagName === desiredTagName) {
                    // found a matching tagName
                    // if we don't have a series yet, start one
                    // if we do have a series, just keep going
                    if (!firstInSeries) {
                        firstInSeries = next;
                    }
                    lastInSeries = next;
                } else {
                    // did not find a matching tagName
                    // if we have a series, then end the series and process it
                    // if we didn't have a series yet, then keep looking for one
                    if (firstInSeries) {
                        // wrap from firstInSeries to next.previousSibling
                        wrapNodes(firstInSeries, lastInSeries);
                        firstInSeries = null;
                    }
                }
            }
            next = next.nextSibling;
        }
        if (firstInSeries) {
            wrapNodes(firstInSeries, lastInSeries);
        }
    }
    wrapChildren(parent);
}

答案 1 :(得分:0)

我不确定你如何将这些体操翻译成原生javascript,但使用jQuery你可以制作自己的方法:jsFiddle

jQuery.fn.wrapConsecutive = function(desiredTagName, wrapTag) {
    $(this).find(desiredTagName).each(function(i, element){
        var $target = $(element);
        $consecutive = $target;
        if(!$target.prev().length || $target.prev().get(0).tagName!==desiredTagName){
            while($target.next().length && $target.next().get(0).tagName===desiredTagName){
                $target = $target.next();
                $consecutive = $consecutive.add($target);
            }
            $consecutive.wrapAll('<' + wrapTag + ' />');
        }
    });
}
$('#relevantbit').wrapConsecutive('P','dd');​
  1. 抓住我们希望分组的每个元素类型
  2. 检查每一个以查看它是否是新组的开始
  3. 检查是否有下一个兄弟,如果是,是否也匹配我们的类型
  4. 包裹成品组
  5. PS:感谢您的评论,这个答案已经过大量修改。