текст замены jQuery, оставляя одноуровневые элементы неповрежденными

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

Демонстрационная разметка:

<fieldset class="myFieldsetClass">
    <legend>Sample Fieldset</legend>
    <ol>
        <li>
            <label>
                <span class="marker">*</span>
                Some Label 1
            </label>
        </li>
        <li>
            <label>
                Some Label 2
            </label>
        </li>
        <li>
            <label>
                Text that doesn't match...
            </label>
        </li>
    </ol>
</fieldset> 

Цель:

  • Заменять текст Some Label X с Some Label (Т.е. удалить X из текста метки).
  • теги span в маркировке должны остаться неповрежденными, если они существуют, такой как <span class="marker"> выше.
  • Я не знаю значение X, который мог быть 1 или более символами долго.

Текущий сценарий:

Мой сценарий jQuery ниже работ, но я знаю, очень неэффективно. Я, может казаться, не обертываю голову вокруг этого по некоторым причинам...

//for each label in the fieldset that contains text "Some Label "
$(".myFieldsetClass label:contains('Some Label ')").each(function() {

    if ($(this).has("span").length > 0) {

        //if the label has the span tag within, remove it and prepend it back to the replaced text
        $(this).find("span").remove().prependTo($(this).text(labelText));

    }
    else {

        //otherwise just replace the text
        $(this).text('Some Label');

    }

});  

Я думал сначала, что я мог просто сделать:

$(".myFieldsetClass label:contains('Some Label ')").text("Some Label");

Но это очищает все содержание маркировки и следовательно удаляет промежуток, который я не хочу. Я не могу использовать функции замены для замены Some Label X с Some Label потому что я не знаю что X будет.

Кто-либо может предложить более изящный/эффективный подход к этой проблеме?

Спасибо.

Править

После попытки нескольких ответов я думаю, что проблема, кажется, что, даже если я выбираю правильный набор, они - текстовые узлы, которые jQuery, кажется, не хочет изменить.. Я использовал FireBug для выбора набора (много ответов ниже всего выбора правильно, но немного отличающимися способами). В консоли поджигателя, заканчивающейся, набор:

[<TextNode textContent="Some Label 1:">,
 <TextNode textContent="Some Label 2:">, 
 <TextNode textContent="Some Label 3:">, 
 <TextNode textContent="Some Label 4:">, 
 <TextNode textContent="Some Label 5:">]

Проблема, кажется, что вызов .replaceWith (), .replace (), .text (), и т.д., кажется, не влияет на набор jQuery. Если я позволяю вышеупомянутому набору содержать один из промежутков, то вызов .replaceWith (), .replace (), и т.д. функционирует правильно против промежутка, но текстовые узлы остаются, как..

12
задан KP. 23 February 2010 в 18:31
поделиться

3 ответа

Попробуйте:

$(".myFieldsetClass label:contains('Some Label ')").contents().filter(':last-child').text("Some Label");

Это должно сработать, если предположить, что текст, который нужно заменить, всегда будет в конце. Функция contents () выбирает все узлы, включая текстовые узлы.

http://api.jquery.com/contents/

РЕДАКТИРОВАТЬ: Я должен был использовать filter () вместо find (). Исправлено.

РЕДАКТИРОВАТЬ: Сейчас работает. Вот один способ.

// Store proper labels in a variable for quick and accurate reference
var $labelCollection = $(".myFieldsetClass label:contains('Some Label ')");

// Call contents(), grab the last one and remove() it
$labelCollection.each(function() {
    $(this).contents().last().remove()
});

// Then simply append() to the label whatever text you wanted.
$labelCollection.append('some text')
10
ответ дан 2 December 2019 в 18:53
поделиться

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

$(".myFieldsetClass label:contains('Some Label ')").contents().filter(function() {
  return this.nodeType == 3 && $(this).is(":contains('Some Label ')");
})
.replaceWith("Some Label");

Однако, если вы знаете, что «Some Label» всегда будет последним элементом в , тогда, я думаю, метод Патрика будет быстрее.

7
ответ дан 2 December 2019 в 18:53
поделиться

Почему бы просто не выполнить полную замену с помощью регулярного выражения?

$(".myFieldsetClass label:contains('Some Label ')")
    .each(function() {
            $(this).html($(this).html().replace(/Some Label ./, "Some Label")); 
        });
2
ответ дан 2 December 2019 в 18:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: