jQuery.replaceWith, меняетсядо </p>? - PullRequest
6 голосов
/ 11 октября 2011

Я работаю с CMS, которая производит теги с двойным разрывом вместо моего предпочтительного тега абзаца.Я попробовал:

$('<br /><br />').replaceWith('</p>');

Теперь, когда вы закончите смеяться;Не могли бы вы сообщить мне, если это возможно, и если да, лучший способ подойти к этому.

Обновление (из комментария ОП):
Абзацы не пусты, они имеют тег <p>начало и последний абзац закрываются с помощью </p>, абзацы между ними разделяются двойным тегом <br>.

У меня нет доступа к коду редактора, и это моя проблема.Это была обычная сборка и ужасная.

Ответы [ 4 ]

3 голосов
/ 21 мая 2012

Есть несколько способов попробовать это.Предпочтительный вариант (поскольку вы уже используете jQuery), вероятно, использует contents () :

$('.your_cms_container').contents().filter(function() {
    return this.nodeType == 3;  // Only text nodes
}).wrap('<p></p>')

. Это обернет все текстовые узлы в теги абзаца.После этого извлекаем все теги
:

$('.your_cms_container').filter('br').remove();

Конечно, все становится сложнее, если ваши текстовые узлы не являются простыми дочерними элементами основного текстового контейнера.

Другой (грязный) вариант - просто манипулировать html вручную, а затем вернуть его обратно в jQuery, как только вы закончите:

var htmlAsString = $('.your_cms_container').html();    // Get the contents as simple text

... // Do nasty things to the string here

$('.your_cms_container').html(htmlAsString);    // Put it back and let jQuery try and sort out any mess

Я не говорю, что второй путь неверен, а иногдаЕдинственный способ добиться цели, не переписывая все.Но это все равно заставляет меня чувствовать себя грязным, если я должен это делать; -)

1 голос
/ 07 октября 2013
  1. Получить все <br> узлы. По желанию, игнорируйте те, которые напрямую внутри блока <p>.
  2. Затем для каждого узла <br> оберните любые текстовые узлы, которые непосредственно предшествуют или следуют за ним.
  3. Наконец, удалите узел <br>.

Этот подход обрабатывает вложение и не удаляет ссылки, макет страницы и т. Д.

код:

$('.your_cms_container br').each ( function () {
    if (this.parentNode.nodeName != "P") {
        $.each ([this.previousSibling, this.nextSibling], function () {
            if (this.nodeType === 3) { // 3 == text
                $(this).wrap ('<p></p>');
            }
        } );

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


Обновление:

После редактирования вопроса ОП я понял, что не совсем решил его конкретную ситуацию. (Я использую приведенный выше код, для большого эффекта в пользовательских скриптах.)

Он хочет изменить это:

<p> "Paragraph 1" <br />
    <a href="http://xkcd.com/246/">Link, the first</a>
    Line after single break.
    <br /><br />
    "Paragraph 2"
</p>

в это:

<p> "Paragraph 1" <br />
    <a href="http://xkcd.com/246/">Link, the first</a>
    Line after single break.
</p>
<p> "Paragraph 2" </p>


Трудности заключаются в следующем: вы не хотите удалять вложенные элементы (если есть) или обработчики событий (если есть).

Для этого используйте следующий подход:

  1. Получите только оскорбительные абзацы с помощью селектора, например p:has(br+br). Помните, что соседний селектор игнорирует текстовые узлы - в данном случае мы этого не хотим.
  2. Перебирайте содержимое каждого нарушающего абзаца, один за другим.
  3. Используйте конечный автомат для создания нового абзаца в каждом <br><br> и для перемещения узлов содержимого в соответствующие <p>.

Код выглядит следующим образом. Вы можете увидеть его в действии на jsFiddle :

var badGraphs   = $("#content p:has(br+br)");
var targetP     = null;
var justSplit   = false;

badGraphs.each ( function () {
    var parentP = $(this);

    parentP.contents ().each ( function (J) {
        if (justSplit) {
            justSplit = false;
            // Continue the loop. Otherwise, it would copy an unwanted <br>.
            return true;    
        }
        var thisjNode   = $(this);
        var nextjNode   = $(this.nextSibling);

        if (thisjNode.is ("br")  &&  nextjNode.is ("br") ) {
            thisjNode.remove (); //-- Kill this <br>
            nextjNode.remove (); //-- and the next

            //-- Create a new p for any following content
            targetP     = targetP || parentP;
            targetP.after ('<p></p>');
            targetP     = targetP.next ("p");

            justSplit   = true;
        }
        else if (targetP) {
            //-- Move the node to its new home.
            targetP.append (this);
        }
    } );
} );
0 голосов
/ 11 октября 2011

Это ответ на ваш вопрос:

$( 'br' ).before( '<p></p>' ).remove();

но, как уже было сказано, лучше делать такие вещи, как на стороне сервера

0 голосов
/ 11 октября 2011

если язык вашего сервера php, вы можете использовать str_replace()

http://php.net/manual/en/function.str-replace.php

...