Как я могу изменить текст элемента, не изменяя его дочерние элементы? - PullRequest
103 голосов
/ 05 ноября 2010

Я бы хотел обновить текст элемента динамически:

<div>
   **text to change**
   <someChild>
       text that should not change
   </someChild>
   <someChild>
       text that should not change
   </someChild>
</div>

Я новичок в jQuery, поэтому эта задача кажется мне довольно сложной.Может кто-нибудь указать мне на функцию / селектор для использования?

Если это возможно, я бы хотел сделать это без добавления нового контейнера для текста, который мне нужно изменить.

Ответы [ 14 ]

60 голосов
/ 05 ноября 2010

У Марка есть лучшее решение с использованием 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);).

57 голосов
/ 05 ноября 2010

Обновление 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>

Обновление 2017 года (adrach):

Похоже, некоторые вещи изменились с тех порбыл опубликован.Вот обновленная версия

$("div").contents().filter(function(){ return this.nodeType == 3; }).first().replaceWith("change text");

Оригинальный ответ (не работает для текущих версий)

$("div").contents().filter(function(){ return this.nodeType == 3; })
.filter(':first').text("change text");

Источник: http://api.jquery.com/contents/

51 голосов
/ 05 ноября 2010

См. В действии

Разметка:

$(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" />
10 голосов
/ 05 ноября 2010
<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");
});

Изменяет только первый текстовый узел

7 голосов
/ 21 ноября 2013

Просто оберните текст, который вы хотите изменить, в интервал с классом для выбора.

Не обязательно отвечает на ваш вопрос, который я знаю, но, возможно, это лучшая практика программирования. Держите вещи в чистоте и простоте

<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')
5 голосов
/ 05 ноября 2010

Для конкретного случая, который вы упомянули:

<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";

Вы не заявляете, как вы хотите обобщить это. Если, скажем, вы хотите изменить текст первого текстового узла внутри <div>, вы можете сделать что-то вроде этого:

var child = div.firstChild;
while (child) {
    if (child.nodeType == 3) {
        child.data = "New text";
        break;
    }
    child = child.nextSibling;
}
2 голосов
/ 19 мая 2016

$.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>
1 голос
/ 22 ноября 2017

Здесь много хороших ответов, но они обрабатывают только один текстовый узел с дочерними элементами. В моем случае мне нужно было работать со всеми текстовыми узлами и игнорировать 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>

Вот jsfiddle , работающий

1 голос
/ 07 марта 2013

Вот пока другой метод: 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);
0 голосов
/ 25 января 2019

2019 vesrsion - Short & Simple

document.querySelector('#your-div-id').childNodes[0].nodeValue = 'new text';

Пояснение

document.querySelector('#your-div-id') используется для выбора родителя (элемент, текст которого вы собираетесь изменить)

.childNodes[0] выделяет текстовый узел

.nodeValue = 'new text' устанавливает значение текстового узла в «новый текст»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...