1

首先原谅我的英语不好。我会尽力解释我的问题!

所以我的问题是我需要拆分 span html 元素,如果它里面有任何这样的元素

<span>
  bla-bla \r\n
    <div>hello</div> 
  world:)
</span>

进入

<span>
  bla-bla \r\n
</span>
<div>
  hello
</div>
<span>
  world:)
</span>

如果 span 有多个 div 或者有多个 span 像

<span class="bold">
  bla 
  <span class="anyclass">
    bla 
    <div>
      Hello
    </div> 
    bla 
    <span class="anyclass#2"> 
      bla-bla 
    </span> 
    <h1>
      amigo
    </h1> 
    <span class="anyclass#3">
      <h2>
        :)
      </h2>
      world
    </span>
  </span> 
  la-la
</span>

它应该分为

<span class="bold">
  bla 
  <span class="anyclass">
    bla 
  </span>
</span>
<div>
  Hello
</div>
<span class="bold">
  <span class="anyclass">
    bla 
    <span class="anyclass#2"> 
      bla-bla 
    </span> 
  </span>
</span>
<h1>
  amigo 
</h1>
<span class="bold">
  <span class="anyclass">
    <span class="anyclass#3">
    </span>
  </span>
</span>
<h2>
  :)
</h2>
<span class="bold">
  <span class="anyclass">
    <span class="anyclass#3">
      world
    </span>
  </span> 
  la-la
</span>

好吧,可能有多个 div 和 h1 或它们中的任何一个在 span 内,或者可能有多个插入的 span 和 div 在其中,我真的陷入了困境。

我知道它看起来令人毛骨悚然,但我需要对它做点什么!

如果任何人都知道如何解决这个拼图或知道一些事情或已经遇到过类似的事情,请帮助我!

多谢!

4

4 回答 4

1

这比看起来要复杂得多。这是我的解决方案:

jsfiddle

function removeSiblings(el, before) {
    var parent = el.parentNode;
    var children = [].slice.call(parent.childNodes);
    var active = !!before;
    for (var i = 0; i < children.length; i++) {
        if (children[i] == el) {
            active = !active;
        } else if (active) {
            parent.removeChild(children[i]);
        }
    }
}

function removeBeforeOrAfter(top, path, before) {
    var els = [];
    for (var i = 0; i < path.length; i++) {
        els.push(restorePath(top, path.slice(0, i + 1)));
    }
    for (var i = 0; i < els.length; i++) {
        removeSiblings(els[i], before);
    }
}

var indexPath = [];
function walkPath(el, condition) {
    if (el.nodeType !== Node.ELEMENT_NODE) {
        return null;
    }
    if (!condition(el)) {
        return el;
    }
    var children = [].slice.call(el.childNodes);
    for (var i = 0; i < children.length; i++) {
        indexPath.push(i);
        var result = walkPath(children[i], condition);
        if (result) {
            return result;
        }
        indexPath.pop();
    }
    return null;
}

function restorePath(el, path) {
    for (var i = 0; i < path.length; i++) {
        el = el.childNodes.item(path[i]);
    }
    return el;
}

function isInlineElement(el) {
    return /^(A|B|BR|CODE|I|IMG|SPAN|STRONG)$/.test(el.tagName); // list not complete
}

function split(wrongNode, topNode, indexPath) {
    var clone = topNode.cloneNode(true);
    var wrongClone = restorePath(clone, indexPath);
    if (topNode.nextSibling) {
        topNode.parentNode.insertBefore(clone, topNode.nextSibling);
    } else {
        topNode.parentNode.appendChild(clone);
    }
    removeBeforeOrAfter(topNode, indexPath, false);
    topNode.parentNode.insertBefore(wrongNode, topNode.nextSibling);
    removeBeforeOrAfter(clone, indexPath, true);
    wrongClone.parentNode.removeChild(wrongClone);
}

$(document).ready(function() {
    var nodes = document.body.childNodes; // live nodeList!
    for (var i = 0; i < nodes.length; i++) {
        var wrongNode = walkPath(nodes[i], isInlineElement);
        if (wrongNode) {
            split(wrongNode, nodes[i], indexPath);
        }
        indexPath = [];
    }
});
于 2012-08-21T19:36:33.133 回答
0

编辑:注意,您可以使用以下 Jquery 代码获得您喜欢的结构

 $(document).ready(function(){

$('span').each(function(){

    $(this).children(':not("span")').before('</span').after('<span>');

});

});

虽然,这是一种肮脏的做事方式,考虑到这种不寻常的期望,我认为这就是方式。缺点是您必须手动检查类或任何属性,并且必须将其添加到要附加的 span 元素中(此处未完成;只是重新排列了 span 元素)。. . .

这是小提琴...

上面的小提琴使用所有非跨度子项,可以根据您的需要过滤到特定标签,如 div h1 h2 等。. . .

于 2012-08-21T04:14:22.580 回答
0

跨度是通用的内联文本元素,内联元素不会创建中断。

div 是除法元素的缩写,它是一个通用的块级元素,它创建中断(默认情况下)。

块元素允许包含其他块元素和内联元素。

内联元素允许包含其他内联元素,但禁止包含块级元素。

换句话说,您不能将 div 元素放在 span 元素中。

如果您希望创建一个换行符,您可以在 span 元素上使用 CSS clear 属性,尽管您不能有效地将除法元素保留在其他 span 元素中,因此请在您遇到糟糕的代码之前修复它。

CSS clean 属性具有以下值:left、right、both、inherit、none。

您可以使用以下任何一种...

span.clear {clear: both;}
span.clear_left {clear: left;}
span.clear_right {clear: right;}

还要从内联元素中删除标题,这只是......不是你的 HTML 的方式。

我强烈建议您进行研究,以极大地提高您对从这里开始的元素上下文的理解......

http://www.w3.org/TR/xhtml11/doctype.html#s_doctype

请记住,您的代码越符合标准,就越容易使用您的代码,因为它降低了任何给定情况的主观性。

于 2012-08-21T02:21:39.180 回答
0

多谢你们!我在想一切,但不是像Pumbaa80那样!

我花了一天时间试图了解它是如何工作的,这似乎是根据需要拆分内联元素的唯一也是最简单的方法!

顺便说一句,它有一个错误 - 在此示例中它不会拆分 span#span2 :

<span id="span1">
  <div id="div1">
    <span id="span2">
      <div id="div2">
        Hello!
      </div>
    </span>
  </div>
</span>

我希望几天后我能完成我的Pumbaa80脚本版本并将其添加到这篇文章中!

于 2012-08-28T16:52:07.207 回答