1

最初に私の悪い英語で失礼します。私の質問をうまく説明しようと思います!

だから私の問題は、そのような要素が内部にある場合、スパンhtml要素を分割する必要があるということです

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

の中へ

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

スパンに複数のdivがある場合、または次のような複数のスパンがある場合

<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またはそれらのいずれかがスパン内にあるか、複数のスパンとdivがそれらの内部に挿入されている可能性があり、私は本当にそれに固執しています。

私はそれが不気味に見えることを知っていますが、私はそれで何かをする必要があります!

enyoneがこのジグソーパズルを解決する方法を知っているか、何かを知っているか、すでにそのような何かに直面している場合は、私を助けてください!

どうもありがとう!

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

みんなありがとう!私はすべてを考えていましたが、Pumbaa80のようには考えていませんでした!

私はそれがどのように機能するかを理解しようと一日を過ごしました、そしてこれが私が必要とするようにインライン要素を分割する唯一のそして最も簡単な方法であるようです!

ちなみに、バグが1つあります。この例では、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 に答える
0

スパンは一般的なインラインテキスト要素であり、インライン要素は区切りを作成しません。

divは、ブレークを作成する一般的なブロックレベルの要素であるdivision要素の略です(デフォルト)。

ブロック要素には、他のブロック要素とインライン要素を含めることができます。

インライン要素には他のインライン要素を含めることができますが、ブロックレベルの要素を含めることは禁止されています。

つまり、スパン要素の中にdiv要素を入れることはできません。

改行を作成したい場合は、スパン要素でCSS clearプロパティを使用できますが、分割要素を他のスパン要素内に有効に保持することはできないため、貧弱なコードを実行する前に修正してください。

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

EDIT:以下のJqueryコードを使用して、好みの構造を取得できることに注意してください

 $(document).ready(function(){

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

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

});

});

これは汚いやり方ですが、この異常な期待を考えると、これはそうでなければならないと思います。欠点は、クラスまたは属性を手動でチェックする必要があり、追加されるスパン要素に追加する必要があることです (ここでは行われません。スパン要素だけが再配置されます)。. . .

これがフィドルです...

上記のフィドルは、ニーズに応じて div h1 h2 などの特定のタグにフィルタリングできるすべての非スパンの子を使用します。. . .

于 2012-08-21T04:14:22.580 に答える