jQuery替换文本,让兄弟姐妹完好无损

时间:2010-02-23 17:39:53

标签: javascript jquery html jquery-selectors

我无法绕过应该是一个简单的解决方案。我想替换标签标签中的文本,而不会影响其他“兄弟姐妹”(如果存在)。

示例加价:

<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来选择集合(下面的许多答案都选择正确,但方式略有不同)。在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(),. renplace(),. text()等似乎不会影响jquery集合。如果我允许上面的集合包含其中一个跨度,那么调用.replaceWith(),. renplace()等对跨度正确运行,但文本节点保持原样。

4 个答案:

答案 0 :(得分:10)

尝试:

$(".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')

答案 1 :(得分:7)

正如帕特里克指出的那样,您可以使用contents()单独选择文本,然后对其进行全部替换。调整那里给出的例子,你也可以尝试:

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

但是,如果您知道“某些标签”将始终是<label>中的最后一个元素,那么帕特里克的方法会更快,我相信。

答案 2 :(得分:2)

为什么不使用正则表达式进行整个替换?

$(".myFieldsetClass label:contains('Some Label ')")
    .each(function() {
            $(this).html($(this).html().replace(/Some Label ./, "Some Label")); 
        });

答案 3 :(得分:0)

单行:

$('.myFieldsetClass label').contents().last().remove().end().first().after('New Label')