Добавлять элемент только тогда, когда "контент / текст" найден - PullRequest
0 голосов
/ 03 июля 2011

Возможно ли с помощью jquery сделать следующее:

Если документ помечен с h1 по h6, добавляйте ссылку «вверх» после каждого элемента заголовка, только если есть текст, написанный послезаголовок и перед следующим ..

Итак:

<h1>h1</h1>
<p>text</p>
<h2>h2</h2>
<h3>h3</h3>
text text
<h4>h4</h4>
<br><br>
<h5>h5</h5>
<br><br>text
<h6>h6</h6>
<div>test</div>

приведет к

<h1>h1</h1>
<p>text</p>
<a..>back to top</a>
<h2>h2</h2>
<h3>h3</h3>
text text
<a..>back to top</a>
<h4>h4</h4>
<br><br>
<h5>h5</h5>
<br><br>text
<a..>back to top</a>
<h6>h6</h6>
<div>test</div>
<a..>back to top</a>

Таким образом, текст может быть в параграфах, div, span или нетотмечен на всех ...

Я не уверен, как это сделать, и как даже выбрать последний элемент перед следующим (или что, если это последний?), чтобы добавить ссылку на.

Любая помощь (не должна быть полным решением) приветствуется.

Редактировать: Самая большая проблема заключается в следующем:

К сожалению, яя работаю с CMS, которая не выводит абзацы, но вместо этого выводит

 <h1>..</h1><br>text<br><br><h2>h2</h2> 

и т. д.

Так же:

<h1>test</h1>
<br>
<h2>test</h2>

с использованиемВторое решение, представленное здесь, которое добавляет верхнюю ссылку, когда это не должно .. Я не уверен, как предотвратить это.

Редактировать 2:

Попытка изменить на:

$('#content').find('h1, h2, h3, h4, h5, h6').each( function(i, item) {
    var nextItems = $(item).nextUntil('h1, h2, h3, h4, h5, h6');

    if (nextItems.filter('p, div, span').size() > 0 || nextItems.filter(function() {
        return this.nodeType == Node.TEXT_NODE;
    }).size() > 0) {
        nextItems.last().after('<p><a href="#toc-top" class="toc-top">Back To Top</a></p>');
    }
});

, но он никогда не находит текстовые узлы .. Есть причина, почему?содержимое - это h2, за которым следуют br и текст ...

Ответы [ 3 ]

1 голос
/ 03 июля 2011

Это достаточно просто, при условии, что вы приложите текст после заголовочные теги с контейнером:

$(document).ready(function() {

    $('h1, h2, h3, h4, h5, h6').each( function(i, item) {
        if ( $(item).nextUntil('h1, h2, h3, h4, h5, h6').text() ) {
            $(item)
                .nextUntil('h1, h2, h3, h4, h5, h6').last()
                .after('<a href="#top">Back To Top</a>');
        }
    });

});

Это работает независимо от того, сколько узлов у вас после заголовков, при условии, что текст обернут в какой-то тег.

Обновление Если вы не можете обернуть текстовые узлы другим тегом, я предлагаю сначала использовать jQuery - это позволит нам последовательно обрабатывать код и обойти ограничение nextUntil. Обновите мой код выше до следующего:

$(document).ready(function() {

    // wrap text nodes with a span
    $('#container') // note that I'm using a container reference to scope this - adjust as needed 
      .contents()
      .filter(function() {
        return this.nodeType == 3; //Node.TEXT_NODE
      }).wrap('<span class="temp" />');

    $('h1, h2, h3, h4, h5, h6').each( function(i, item) {
        var items = $(item).nextUntil('h1, h2, h3, h4, h5, h6');
        if ( items.text().match(/[^\s]/gi) ) {
            // Only insert a back to top link if these nodes contain at least one non-whitespace character
            items.last()
                .after('<a href="#top">Back To Top</a>');
        }
    });

    $('#container').find('span.temp').replaceWith(function () {
        return $(this).text();
    });

});

Вот jsfiddle

1 голос
/ 03 июля 2011
$("h1,h2,h3,h4,h5,h6").next('p,div,span').after('<a>To Top</a>');

Самый быстрый, который я мог придумать. Не будет работать, если текст не находится в контейнере. Если вы можете обернуть контейнер вокруг текста перед вставкой, это будет легко.

$('yourcontainer').each(function(){
    if($(this).text() != "") {
        $(this).after('<a>To Top</a>');
    }
});

EDIT

Я думаю, что другие предоставленные ответы хороши, может сработать, но я вижу шаблон в вашем выводе и, следовательно, предоставляю вам следующее простое предложение: $("h1,h2,h3").next('br').next('br').next('br').after('<a>To top</a>');

Предположение: Ваш паттерн (<htag>htag</htag><br>if(text){<br>text<br>})*

0 голосов
/ 03 июля 2011

Вы можете использовать метод .contents () для распознавания текстовых узлов.

    $(document).ready(function () {
        $('#content').contents()
            .filter(function () { return (this.nodeType == 3); })
            .wrap('<p class="temp"></p>');

        var headers = "h1,h2,h3,h4,h5,h6";
        $(headers).each(function () {
            var $currentHeader = $(this);
            if ($currentHeader.is('h6')) {
                var $siblings = $currentHeader.nextAll();
                if ($siblings.text().trim()) {
                    $siblings.last().after('<a href="#">Top</a>');
                }
            }
            else {
                if ($currentHeader.nextUntil(headers).text().trim()) {
                    $currentHeader.nextAll(headers).first().before('<a href="#">Top</a>');
                }
            }
        });

        $('#content').find('.temp').replaceWith(function () {
            return $(this).text();
        });

    });

По сути, я нахожу все текстовые узлы и помещаю их во временную <p>.Затем мы добавляем <a> элементы, где это необходимо.После завершения всей обработки мы безопасно удаляем временные элементы <p>.

Jsfiddle Link: http://jsfiddle.net/amritayan/GXLFL/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...