javascript - <a>タグが混在するテキストノードをjQueryでラップする方法は?

原文 javascript jquery html

私はjQueryの初心者です。 chrome拡張を作りたいです。しかし、いくつかのウェブページは次のようなHTMLを持っています。これを前処理してクリーンにしたいと考えています。

<div>
  Hello 
  <a href="#">World</a>
  !!!!!!
  <br />
  Nice to meet you
  <img src="#">
</div>


<br>タグで区切られたすべてのテキストノードをpタグにラップしますが、間にあるaタグをスキップして、最後に<br>タグを削除します。 (aタグをスキップするだけで、他のタグはスキップされず、テキストはその時点までラップされます)。上記の例は、次のように変換する必要があります。

<div>
  <p>Hello <a href="#">World</a>!!!!!!</p>
  <p>Nice to meet you</p>
  <img src="#">
</div>


jQueryを使用して上記の変換を行う方法を教えてください。

関連する回答を見つけましたが、aタグをスキップする方法がわかりません。

$("body br").each(function () {
  $.each([this.previousSibling, this.nextSibling], function() {
    if (this.nodeType === 3) { 
      $(this).wrap('<p></p>');
    }
    // Should skip over a tags
  });

  $(this).remove(); 
});


別の試みが失敗しました(マージされる最後の要素が2回表示されます)。



$("body br").each(function() {
  $.each([this.previousSibling, this.nextSibling], function() {
    if (this.nodeType === 3) {
      $(this).wrap('<p></p>');
    }
    // Should skip over a tags
  });

  $(this).remove();
});

//Wrap all <br> tags with <p>
var to_be_deleted = new Array();
var just_finished = false;

function is_finished() {
  return just_finished;
}

function set_finished(val) {
  just_finished = val;
}

$('body br').each(function() {
  $.each([this.previousSibling, this.nextSibling], function() {
    if (this.nodeType === 3) { // 3 == text
      if ($(this).parent().is("p")) {
        console.log("Parent is p");
      }
      if (this.nextSibling) {

        var curr = this.nextSibling;
        var count = 0; // How many elements merged
        var till_now = $('<p class="merged_block">');
        $(till_now).append($(this).clone());
        while (curr) {
          if (curr.tagName === "A") {
            var a_elem = $(curr).clone();
            $(till_now).append(a_elem);
            to_be_deleted.push(curr);
            count++;

          } else if (curr.nodeType === 3) {
            var n_elem = $(curr).clone();
            $(till_now).append(n_elem);
            to_be_deleted.push(curr);
            count++;

          } else {
            break;
          }

          curr = curr.nextSibling;
        }

        if (count > 0) {
          $(this).before(till_now);
          $(this).remove();
          set_finished(true);
        }

      } else {
        if (is_finished()) {
          $(this).remove();
          set_finished(false);
        } else {
          $(this).wrap('<p></p>'); // Last <br/>
        }

      }
    }
  });

  $(this).remove(); //-- Kill the <br>
});

$.each(to_be_deleted, function(i, e) {
  $(e).remove();
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  Hello <a href="#">World</a> blablah
  <br /> Nice to meet you
  <img src="#">
</div>
答え
これが私が問題を解決した方法です:



$(document).ready(function(){
    var dad = document.getElementById("dad"),
        container = document.getElementById("container"),
        elem = container.childNodes,
        parent = document.createElement("div"),
        newElem = document.createElement("p");

    while($(container).html() !== "") {
        if (elem[0].nodeName == "#text") {
            newElem.appendChild(elem[0]);
            elem.data = "";
        } else if (elem[0].nodeName == "BR") {
            parent.appendChild(newElem);
            newElem = document.createElement("p");
            container.removeChild(elem[0]);
        } else {
            newElem.appendChild(elem[0]);
            container.removeChild(elem[0]);
        }
    }
    parent.appendChild(newElem);
    newElem = document.createElement("p");

    dad.removeChild(container);
    parent.id = "container";
    dad.appendChild(parent);
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body id="dad">
  <div class="container" id="container">
    Hello 
    <a href="#">World</a>
    !!!!!!
    <br />
    Nice to meet you
    <img src="#">
  </div>
</body>
関連記事

javascript - MVCプロジェクトのアクションから返されたHTMLファイルのスクリプトへのパスが正しくありません

javascript - ドロップダウンに表示される複数のcssファイルからCSSクラスのリストを取得します

javascript - HTMLに解析されたJSONデータの<script>タグのエスケープ/削除

javascript - Knockoutjsクリックバインディングが機能しなくなった

javascript - JavaScriptを使用して範囲を強調表示できない

javascript - node.jsのjQueryパッケージに$ .ajaxメソッドがないのはなぜですか?

javascript - 重複のAngular ng-repeat

javascript - iPadのフルカレンダーバージョン2のドラッグイベント

javascript - コマンドラインクライアントと対話する

javascript - JavaScriptの配列値をスキップしますか?