Как изменить текст элемента без изменения его дочерних элементов?
Я хочу динамически обновлять текст элемента:
<div>
**text to change**
<someChild>
text that should not change
</someChild>
<someChild>
text that should not change
</someChild>
</div>
Я новичок в jQuery, поэтому эта задача кажется для меня довольно сложной задачей.
Может ли кто-нибудь указать мне на функцию/селектор, чтобы использовать?
Если это возможно, я бы хотел сделать это, не добавляя новый контейнер для текста, который мне нужно изменить.
Ответы
Ответ 1
Знаки получили лучшее решение с использованием jQuery, но вы также можете сделать это и в обычном JavaScript.
В Javascript свойство childNodes
предоставляет вам все дочерние узлы элемента, включая текстовые узлы.
Итак, если вы знали, что текст, который вы хотите изменить, всегда будет первым элементом в элементе, а затем дается, например, этот HTML:
<div id="your_div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>
Вы можете сделать это:
var your_div = document.getElementById('your_div');
var text_to_change = your_div.childNodes[0];
text_to_change.nodeValue = 'new text';
Конечно, вы все равно можете использовать jQuery для выбора <div>
в первую очередь (т.е. var your_div = $('your_div').get(0);
).
Ответ 2
Обновление 2018
Поскольку это довольно популярный ответ, я решил немного обновить и украсить его, добавив селектор textnode в jQuery в качестве плагина.
В приведенном ниже фрагменте вы можете видеть, что я определяю новую функцию jQuery, которая получает все (и только) textNodes. Вы можете также связать эту функцию с помощью функции first()
. Я делаю обрезку текстового узла и проверяю, не пуст ли он после обрезки, потому что пробелы, табуляции, новые строки и т.д. Также распознаются как текстовые узлы. Если вам тоже нужны эти узлы, просто удалите это из оператора if в функции jQuery.
Я добавил пример, как заменить первый текстовый узел и как заменить все текстовые узлы.
Такой подход облегчает чтение кода и позволяет использовать его несколько раз и для разных целей.
Обновление 2017 года (adrach) также должно работать, если вы предпочитаете это.
jQuery.fn.textNodes = function() {
return this.contents().filter(function() {
return (this.nodeType === Node.TEXT_NODE && this.nodeValue.trim() !== "");
});
}
$(document).ready(function(){
$('#replaceAll').on('click', function() {
$('#testSubject').textNodes().replaceWith('Replaced');
});
$('#replaceFirst').on('click', function() {
$('#testSubject').textNodes().first().replaceWith('Replaced First');
});
});
p {
margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testSubject">
**text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**also text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**last text to change**
</div>
<button id="replaceFirst">Replace First</button>
<button id="replaceAll">Replace All</button>
Ответ 3
Разметка:
$(function() {
$('input[type=button]').one('click', function() {
var cache = $('#parent').children();
$('#parent').text('Altered Text').append(cache);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">Some text
<div>Child1</div>
<div>Child2</div>
<div>Child3</div>
<div>Child4</div>
</div>
<input type="button" value="alter text" />
Ответ 4
<div id="divtochange">
**text to change**
<div>text that should not change</div>
<div>text that should not change</div>
</div>
$(document).ready(function() {
$("#divtochange").contents().filter(function() {
return this.nodeType == 3;
})
.replaceWith("changed text");
});
Это изменяет только первый текстовый индекс
Ответ 5
Просто оберните текст, который вы хотите изменить, в диапазоне с выбранным классом.
Не обязательно отвечать на ваш вопрос, который я знаю, но, вероятно, лучше практика кодирования. Держите вещи чистыми и простыми
<div id="header">
<span class="my-text">**text to change**</span>
<div>
text that should not change
</div>
<div>
text that should not change
</div>
</div>
Вуаля!
$('#header .mytext').text('New text here')
Ответ 6
В данном конкретном случае вы упомянули:
<div id="foo">
**text to change**
<someChild>
text that should not change
</someChild>
<someChild>
text that should not change
</someChild>
</div>
... это очень просто:
var div = document.getElementById("foo");
div.firstChild.data = "New text";
Вы не указываете, как вы хотите обобщить это. Если, скажем, вы хотите изменить текст первого текста node в <div>
, вы можете сделать что-то вроде этого:
var child = div.firstChild;
while (child) {
if (child.nodeType == 3) {
child.data = "New text";
break;
}
child = child.nextSibling;
}
Ответ 7
$.fn.textPreserveChildren = function(text) {
return this.each(function() {
return $(this).contents().filter(function() {
return this.nodeType == 3;
}).first().replaceWith(text);
})
}
setTimeout(function() {
$('.target').textPreserveChildren('Modified');
}, 2000);
.blue {
background: #77f;
}
.green {
background: #7f7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="target blue">Outer text
<div>Nested element</div>
</div>
<div class="target green">Another outer text
<div>Another nested element</div>
</div>
Ответ 8
Вот еще один метод: http://jsfiddle.net/qYUBp/7/
HTML
<div id="header">
**text to change**
<div>
text that should not change
</div>
<div>
text that should not change
</div>
</div>
JQuery
var tmp=$("#header>div").html();
$("#header").text("its thursday").append(tmp);
Ответ 9
Здесь много замечательных ответов, но они обрабатывают только один текстовый узел с детьми. В моем случае мне нужно было работать на всех текстовых узлах и игнорировать html файлы, НО СОХРАНЯТЬ ЗАКАЗ.
Поэтому, если у нас есть такой случай:
<div id="parent"> Some text
<div>Child1</div>
<div>Child2</div>
and some other text
<div>Child3</div>
<div>Child4</div>
and here we are again
</div>
Мы можем использовать следующий код для изменения только текста и СОХРАНЕНИЯ ЗАКАЗА
$('#parent').contents().filter(function() {
return this.nodeType == Node.TEXT_NODE && this.nodeValue.trim() != '';
}).each(function() {
//You can ignore the span class info I added for my particular application.
$(this).replaceWith(this.nodeValue.replace(/(\w+)/g,"<span class='IIIclassIII$1' onclick='_mc(this)' onmouseover='_mr(this);' onmouseout='_mt(this);'>$1X</span>"));
});
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<div id="parent"> Some text
<div>Child1</div>
<div>Child2</div>
and some other text
<div>Child3</div>
<div>Child4</div>
and here we are again
</div>
Ответ 10
Я думаю, что вы ищете .prependTo().
http://api.jquery.com/prependTo/
Мы также можем выбрать элемент на страницы и вставьте ее в другую:
$( 'h2') prependTo ($ ( 'контейнер.'));.
Если элемент, выбранный таким образом, вставлен в другое место, он будет перемещен в цель (не клонировано):
<div class="container">
<h2>Greetings</h2>
<div class="inner">Hello</div>
<div class="inner">Goodbye</div>
</div>
Если существует более одной цели элемент, однако, клонированные копии вставленный элемент будет создан для каждая цель после первого.
Ответ 11
Простой ответ:
$("div").contents().filter(function(){
return this.nodeType == 3;
})[0].nodeValue = "The text you want to replace with"
Ответ 12
Проблема с ответом Марка заключается в том, что вы также получаете пустые текстовые поля. Решение как плагин jQuery:
$.fn.textnodes = function () {
return this.contents().filter(function (i,n) {
return n.nodeType == 3 && n.textContent.trim() !== "";
});
};
$("div").textnodes()[0] = "changed text";
Ответ 13
Это старый вопрос, но вы можете сделать простую функцию, подобную этой, чтобы сделать вашу жизнь проще:
$.fn.toText = function(str) {
var cache = this.children();
this.text(str).append(cache);
}
Пример:
<div id="my-div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>
Использование:
$("#my-div").toText("helloworld");
Ответ 14
2019 vesrsion - Короткая и короткая версия Простой
document.querySelector('#your-div-id').childNodes[0].nodeValue = 'new text';
Объяснение
document.querySelector('#your-div-id')
используется для выбора родителя (элемент, текст которого вы собираетесь изменить)
.childNodes[0]
выбирает текстовый узел
.nodeValue = 'new text'
устанавливает значение текстового узла в "новый текст"
Этот ответ, возможно, вдохновлен комментарием Дина Мартина. Не могу сказать наверняка, так как я использую это решение в течение многих лет. Просто подумал, что я должен опубликовать эту вероятность здесь, потому что некоторые люди заботятся об этом больше, чем тот факт, что это лучшее решение.