如何使用jQuery在span内更改文本,使其他span中包含的节点保持原样?

时间:2022-11-29 10:32:14

I have the following HTML snippet:

我有以下HTML片段:

<span class="target">Change me <a class="changeme" href="#">now</a></span>

I'd like to change the text node (i.e. "Change me ") inside the span from jQuery, while leaving the nested <a> tag with all attributes etc. intact. My initial huch was to use .text(...) on the span node, but as it turns out this will replace the whole inner part with the passed textual content.

我想要更改文本节点(即。“改变我”))在jQuery生成的span内,保留嵌套的具有所有属性等的标签。我最初的huch是在span节点上使用.text(…),但事实证明,这将用传递的文本内容替换整个内部部分。

I solved this with first cloning the <a> tag, then setting the new text content of <span> (which will remove the original <a> tag), and finally appending the cloned <a> tag to my <span>. This works, but feels such an overkill for a simple task like this. Btw. I can't guarantee that there will be an initial text node inside the span - it might be empty, just like:

我首先克隆了标记,然后设置了的新文本内容(它将删除原始的标记),最后将克隆的标记附加到我的。这是可行的,但是对于这样一个简单的任务来说,这就太过了。顺便说一句。我不能保证span中会有一个初始的文本节点——它可能是空的,就像:

<span class="target"><a class="changeme" href="#">now</a></span>

I did a jsfiddle too. So, what would be the neat way to do this?

我也演奏了小提琴。那么,最简洁的方法是什么呢?

8 个解决方案

#1


6  

Try something like:

尝试:

$('a.changeme').on('click', function() {
  $(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again ');
});

demo: http://jsfiddle.net/eEMGz/

演示:http://jsfiddle.net/eEMGz/

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

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

Update:

更新:

I guess I read your question wrong, and you're trying to replace the text if it's already there and inject it otherwise. For this, try:

我猜我读错了你的问题,你试图替换文本如果它已经在那里,并注入它。为此,尝试:

$('a.changeme').on('click', function() {
  var
    $tmp = $(this).closest('.target').contents().not(this).eq(0),
    dia = document.createTextNode('Do it again ');

  $tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this);
});

​Demo: http://jsfiddle.net/eEMGz/3/

演示:http://jsfiddle.net/eEMGz/3/

#2


1  

You can use .contents():

您可以使用.contents():

//set the new text to replace the old text
var newText = 'New Text';

//bind `click` event handler to the `.changeme` elements
$('.changeme').on('click', function () {

    //iterate over the nodes in this `<span>` element
    $.each($(this).parent().contents(), function () {

        //if the type of this node is undefined then it's a text node and we want to replace it
        if (typeof this.tagName == 'undefined') {

            //to replace the node we can use `.replaceWith()`
            $(this).replaceWith(newText);
        }
    });
});​

Here is a demo: http://jsfiddle.net/jasper/PURHA/1/

这里有一个演示:http://jsfiddle.net/jasper/PURHA/1/

Some docs for ya:

丫的一些文档:

Update

var newText = 'New Text';
$('a').on('click', function () {
    $.each($(this).parent().contents(), function () {
        if (typeof this.tagName == 'undefined') {

            //instead of replacing this node with the replacement string, just replace it with a blank string
            $(this).replaceWith('');
        }
    });

    //then add the replacement string to the `<span>` element regardless of it's initial state
    $(this).parent().prepend(newText);
});​

Demo: http://jsfiddle.net/jasper/PURHA/2/

演示:http://jsfiddle.net/jasper/PURHA/2/

#3


1  

You can try this.

你可以试试这个。

var $textNode, $parent;
$('.changeme').on('click', function(){
    $parent = $(this).parent(); 
    $textNode= $parent.contents().filter(function() {
            return this.nodeType == 3;
    });
    if($textNode.length){
        $textNode.replaceWith('Content changed')
    }
    else{
        $parent.prepend('New content');
    }
});

Working demo - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/

工作演示——http://jsfiddle.net/ShankarSangoli/yx5Ju/8/

#4


1  

You step out of jQuery because it doesn't help you to deal with text nodes. The following will remove the first child of every <span> element with class "target" if and only if it exists and is a text node.

退出jQuery是因为它不能帮助您处理文本节点。下面将删除每个元素的第一个子元素,其类为“target”,如果且仅当它存在并且是一个文本节点时。

Demo: http://jsfiddle.net/yx5Ju/11/

演示:http://jsfiddle.net/yx5Ju/11/

Code:

代码:

$('span.target').each(function() {
    var firstChild = this.firstChild;
    if (firstChild && firstChild.nodeType == 3) {
        firstChild.data = "Do it again";
    }
});

#5


0  

This is not a perfect example I guess, but you could use contents function.

我猜这不是一个完美的例子,但是你可以使用contents函数。

console.log($("span.target").contents()[0].data);

#6


0  

You could wrap the text into a span ... but ...

你可以把文字压缩成一个跨度……但是…

try this. http://jsfiddle.net/Y8tMk/

试试这个。http://jsfiddle.net/Y8tMk/

$(function(){
    var txt = '';
    $('.target').contents().each(function(){
        if(this.nodeType==3){
                    this.textContent = 'done ';
        }
    });
});

#7


0  

You can change the native (non-jquery) data property of the object. Updated jsfiddle here: http://jsfiddle.net/elgreg/yx5Ju/2/

您可以更改对象的本机(非jquery)数据属性。更新jsfiddle:http://jsfiddle.net/elgreg/yx5Ju/2/

Something like:

喜欢的东西:

$('a.changeme3').click(function(){
    $('span.target3').contents().get(0).data = 'Do it again';
});

The contents() gets the innards and the get(0) gets us back to the original element and the .data is now a reference to the native js textnode. (I haven't tested this cross browser.)

contents()获取内部结构,get(0)返回原始元素,.data现在是对本机js textnode的引用。(我还没有测试过这个跨浏览器。)

This jsfiddle and answer are really just an expanded explanation of the answer to this question: Change text-nodes text

这个jsfiddle和答案实际上只是对这个问题的答案的扩展解释:改变文本节点文本。

#8


0  

$('a.changeme').click(function() {                         
    var firstNode= $(this).parent().contents()[0];
        if( firstNode.nodeType==3){
        firstNode.nodeValue='New text';
    }
})

EDIT: not sure what layout rules you need, update to test only first node, otherwise adapt as needed

编辑:不确定需要什么布局规则,只更新到测试第一个节点,否则根据需要进行调整

#1


6  

Try something like:

尝试:

$('a.changeme').on('click', function() {
  $(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again ');
});

demo: http://jsfiddle.net/eEMGz/

演示:http://jsfiddle.net/eEMGz/

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

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

Update:

更新:

I guess I read your question wrong, and you're trying to replace the text if it's already there and inject it otherwise. For this, try:

我猜我读错了你的问题,你试图替换文本如果它已经在那里,并注入它。为此,尝试:

$('a.changeme').on('click', function() {
  var
    $tmp = $(this).closest('.target').contents().not(this).eq(0),
    dia = document.createTextNode('Do it again ');

  $tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this);
});

​Demo: http://jsfiddle.net/eEMGz/3/

演示:http://jsfiddle.net/eEMGz/3/

#2


1  

You can use .contents():

您可以使用.contents():

//set the new text to replace the old text
var newText = 'New Text';

//bind `click` event handler to the `.changeme` elements
$('.changeme').on('click', function () {

    //iterate over the nodes in this `<span>` element
    $.each($(this).parent().contents(), function () {

        //if the type of this node is undefined then it's a text node and we want to replace it
        if (typeof this.tagName == 'undefined') {

            //to replace the node we can use `.replaceWith()`
            $(this).replaceWith(newText);
        }
    });
});​

Here is a demo: http://jsfiddle.net/jasper/PURHA/1/

这里有一个演示:http://jsfiddle.net/jasper/PURHA/1/

Some docs for ya:

丫的一些文档:

Update

var newText = 'New Text';
$('a').on('click', function () {
    $.each($(this).parent().contents(), function () {
        if (typeof this.tagName == 'undefined') {

            //instead of replacing this node with the replacement string, just replace it with a blank string
            $(this).replaceWith('');
        }
    });

    //then add the replacement string to the `<span>` element regardless of it's initial state
    $(this).parent().prepend(newText);
});​

Demo: http://jsfiddle.net/jasper/PURHA/2/

演示:http://jsfiddle.net/jasper/PURHA/2/

#3


1  

You can try this.

你可以试试这个。

var $textNode, $parent;
$('.changeme').on('click', function(){
    $parent = $(this).parent(); 
    $textNode= $parent.contents().filter(function() {
            return this.nodeType == 3;
    });
    if($textNode.length){
        $textNode.replaceWith('Content changed')
    }
    else{
        $parent.prepend('New content');
    }
});

Working demo - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/

工作演示——http://jsfiddle.net/ShankarSangoli/yx5Ju/8/

#4


1  

You step out of jQuery because it doesn't help you to deal with text nodes. The following will remove the first child of every <span> element with class "target" if and only if it exists and is a text node.

退出jQuery是因为它不能帮助您处理文本节点。下面将删除每个元素的第一个子元素,其类为“target”,如果且仅当它存在并且是一个文本节点时。

Demo: http://jsfiddle.net/yx5Ju/11/

演示:http://jsfiddle.net/yx5Ju/11/

Code:

代码:

$('span.target').each(function() {
    var firstChild = this.firstChild;
    if (firstChild && firstChild.nodeType == 3) {
        firstChild.data = "Do it again";
    }
});

#5


0  

This is not a perfect example I guess, but you could use contents function.

我猜这不是一个完美的例子,但是你可以使用contents函数。

console.log($("span.target").contents()[0].data);

#6


0  

You could wrap the text into a span ... but ...

你可以把文字压缩成一个跨度……但是…

try this. http://jsfiddle.net/Y8tMk/

试试这个。http://jsfiddle.net/Y8tMk/

$(function(){
    var txt = '';
    $('.target').contents().each(function(){
        if(this.nodeType==3){
                    this.textContent = 'done ';
        }
    });
});

#7


0  

You can change the native (non-jquery) data property of the object. Updated jsfiddle here: http://jsfiddle.net/elgreg/yx5Ju/2/

您可以更改对象的本机(非jquery)数据属性。更新jsfiddle:http://jsfiddle.net/elgreg/yx5Ju/2/

Something like:

喜欢的东西:

$('a.changeme3').click(function(){
    $('span.target3').contents().get(0).data = 'Do it again';
});

The contents() gets the innards and the get(0) gets us back to the original element and the .data is now a reference to the native js textnode. (I haven't tested this cross browser.)

contents()获取内部结构,get(0)返回原始元素,.data现在是对本机js textnode的引用。(我还没有测试过这个跨浏览器。)

This jsfiddle and answer are really just an expanded explanation of the answer to this question: Change text-nodes text

这个jsfiddle和答案实际上只是对这个问题的答案的扩展解释:改变文本节点文本。

#8


0  

$('a.changeme').click(function() {                         
    var firstNode= $(this).parent().contents()[0];
        if( firstNode.nodeType==3){
        firstNode.nodeValue='New text';
    }
})

EDIT: not sure what layout rules you need, update to test only first node, otherwise adapt as needed

编辑:不确定需要什么布局规则,只更新到测试第一个节点,否则根据需要进行调整