Я испытываю затруднения при переносе моей головы, что должно быть простым решением. Я хочу заменить текст в теге 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 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 (), и т.д. функционирует правильно против промежутка, но текстовые узлы остаются, как..
Попробуйте:
$(".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')
Как указывает Патрик, вы можете использовать contents ()
для выбора только текст, а затем сделайте замену всего этого. Адаптировав приведенный там пример, вы также можете попробовать:
$(".myFieldsetClass label:contains('Some Label ')").contents().filter(function() {
return this.nodeType == 3 && $(this).is(":contains('Some Label ')");
})
.replaceWith("Some Label");
Однако, если вы знаете, что «Some Label» всегда будет последним элементом в
, тогда, я думаю, метод Патрика будет быстрее.
Почему бы просто не выполнить полную замену с помощью регулярного выражения?
$(".myFieldsetClass label:contains('Some Label ')")
.each(function() {
$(this).html($(this).html().replace(/Some Label ./, "Some Label"));
});