javascript 如何使用 jQuery 更改跨度内的文本,而保持其他跨度包含的节点完好无损?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9487418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change text inside span with jQuery, leaving other span contained nodes intact?
提问by András Szepesházi
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 outthis will replace the whole inner part with the passed textual content.
我想从 jQuery 更改跨度内的文本节点(即“更改我”),同时保留<a>
带有所有属性等的嵌套标记。我最初的想法是.text(...)
在 span 节点上使用,但事实证明这将用传递的文本内容替换整个内部部分。
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:
我通过首先克隆<a>
标签解决了这个问题,然后设置了<span>
(这将删除原始<a>
标签)的新文本内容,最后将克隆的<a>
标签附加到我的<span>
. 这有效,但对于这样的简单任务来说感觉太过分了。顺便提一句。我不能保证跨度内会有一个初始文本节点 - 它可能是空的,就像:
<span class="target"><a class="changeme" href="#">now</a></span>
I did a jsfiddletoo. So, what would be the neat way to do this?
我也做了一个jsfiddle。那么,这样做的巧妙方法是什么?
回答by Yoshi
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/
回答by Tim Down
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 是因为它无法帮助您处理文本节点。<span>
当且仅当它存在并且是文本节点时,以下内容将删除具有类“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";
}
});
回答by Jasper
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:
一些文档给你:
.contents()
: http://api.jquery.com/contents.replaceWith()
: http://api.jquery.com/replacewithtypeof
: https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof
.contents()
:http: //api.jquery.com/contents.replaceWith()
:http: //api.jquery.com/replacewithtypeof
: https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof
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);
});?
回答by ShankarSangoli
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/
回答by Mikhas
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 ';
}
});
});
回答by elgreg
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 和答案实际上只是对这个问题的答案的扩展解释: 更改文本节点文本
回答by charlietfl
$('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
编辑:不确定您需要什么布局规则,更新以仅测试第一个节点,否则根据需要进行调整