자식 요소를 변경하지 않고 요소의 텍스트를 어떻게 변경할 수 있습니까?


120

요소의 텍스트를 동적으로 업데이트하고 싶습니다.

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

저는 jQuery를 처음 사용하기 때문에이 작업은 저에게 상당히 어려운 것 같습니다. 누군가가 사용할 기능 / 선택기를 가리킬 수 있습니까?

가능하다면 변경해야 할 텍스트에 대한 새 컨테이너를 추가하지 않고 수행하고 싶습니다.


7
"가능하다면 변경해야하는 텍스트에 대한 새 컨테이너를 추가하지 않고 수행하고 싶습니다." - 정말? 컨테이너가 있으면 훨씬 쉬울 테니까요.
Paul D. Waite

얘들 아, 난 원래의 질문 쳐다 보면서 나는 영업 이익은 자식 요소에 대해 아무것도 말했다 생각하지 않습니다 ...
SIME VIDAS

W3 표준에 따르면 div는 텍스트 노드도 가질 수 없습니다 (정확한 것을 기억한다면). <p>, <h1> 등과 같은 텍스트 컨테이너를 추가해야합니다.
Mark Baijens 2010

2
@Mark : (X) HTML Strict 일 가능성이 있지만 더 이상은 아닙니다. (HTML5는 지금 여기에 있습니다.)
Paul D. Waite

@Matt Ball : 실제 HTML에는 someChild 대신 span 태그가 있습니다.
ika

답변:


75

Mark는 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';

물론 <div>처음부터 jQuery를 사용하여를 선택할 수 있습니다 (예 :) var your_div = $('your_div').get(0);.


1
텍스트 노드를 바꿀 필요가 없습니다. 기존 자산 data또는 nodeValue속성을 변경하기 만하면 됩니다.
Tim Down

@ 팀 : 아, 더 쉬운 방법이 있어야한다고 생각했습니다. jQuery가 나오기 전에는 JavaScript를 많이 사용하지 않았습니다. 건배, 그에 따라 답변을 수정하겠습니다.
Paul D. Waite

11
따라서이 답변의 최신 구현은$('#yourDivId')[0].childNodes[0].nodeValue = 'New Text';
Dean Martin

짧고 간단한 솔루션은 지금까지 - stackoverflow.com/a/54365288/4769218
실버 Ringvee

1
"당신은 너무 일반 자바 스크립트에서이 작업을 수행 할 수있을 것"
duhaime

65

2018 업데이트

이것은 꽤 인기있는 답변이기 때문에 jQuery에 플러그인으로 textnode 선택기를 추가하여 약간 업데이트하고 아름답게하기로 결정했습니다.

아래 스 니펫에서 textNode를 모두 가져 오는 새 jQuery 함수를 정의한 것을 볼 수 있습니다. 이 함수를 예를 들어 함수와 연결할 수도 있습니다 first(). 텍스트 노드에서 트리밍을 수행하고 공백, 탭, 새 줄 등도 텍스트 노드로 인식되기 때문에 트리밍 후 비어 있지 않은지 확인합니다. 이러한 노드도 필요하면 jQuery 함수의 if 문에서 간단히 제거하십시오.

첫 번째 텍스트 노드를 바꾸는 방법과 모든 텍스트 노드를 바꾸는 방법에 대한 예제를 추가했습니다.

이 접근 방식을 사용하면 코드를 더 쉽게 읽을 수 있고 다른 용도로 여러 번 사용하기가 더 쉽습니다.

업데이트 2017 (adrach는) 당신이 선호하는 경우 여전히 잘 작동한다.

jQuery 확장으로

Javascript (ES) eqivilant


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/


아하! 어딘가에 영리한 jQuery 함수가 있다는 것을 알았습니다. 작성한 솔루션의 유일한 문제는 모든 텍스트 노드가 다음 텍스트를 얻는다는 것입니다 (예 : 하위 요소 내의 텍스트 포함). 나는 그것을 제한하는 것이 너무 어렵지 않을 것이라고 생각합니까?
Paul D. Waite

10
을 사용하는 데 문제가 .filter(':first')있었지만 .first()대신을 사용하면 효과가있었습니다. 감사!
hollaburoo

16
이것은 나를 위해 작동하지 않습니다 .text()(볼 이 jsfiddle을 )하지만 함께하지 .replaceWith()( 여기 jsfiddle ).
magicalex

2
이것은 나를 위해 작동합니다. textObject = $ (myNode) .contents (). filter (function () {return this.nodeType == 3;}) [0] $ (textObject) .replaceWith ( "my text" );
Maragues 2012 년

nodeType=3그것에 대해 궁금한 사람 은 "TEXT"의 노드 유형 만 필터링 하는 것입니다. w3schools.com/jsref/prop_node_nodetype.asp 자세한 정보
ktutnik

53

실제보기

마크 업 :

$(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" />


6
내가 만난 최고의 솔루션입니다. 우아하고 단순합니다.
Yoav Kadosh 2013-06-24

3
그러나 이것은 노드의 순서를 유지하지 않습니다. 예를 들어 텍스트가 먼저 요소의 끝에 있었다면 이제 시작에있을 것입니다.
Matt

순서를 유지하지는 않지만 대부분의 경우 텍스트를 첫 번째 또는 마지막 노드로 원합니다. 따라서 append ()가 원하는 결과를 얻지 못하면 기존 자식을 텍스트 앞에 넣으려면 prepend ()를 시도하십시오.
Sensei

짧고 간단한 솔루션은 지금까지 - stackoverflow.com/a/54365288/4769218
실버 Ringvee

11
<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");
});

이것은 첫 번째 텍스트 노드 만 변경합니다.


9

선택할 클래스로 범위에서 변경하려는 텍스트를 감싸기 만하면됩니다.

내가 아는 질문에 반드시 답하는 것은 아니지만 아마도 더 나은 코딩 방법 일 것입니다. 깨끗하고 단순하게 유지하십시오

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

Voilà!

$('#header .mytext').text('New text here')

이것이 최고의 솔루션입니다!
Sleek Geek

5

언급 한 특정 사례에 대해 :

<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

$.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

다음은 다른 방법 : 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);

1

여기에 많은 훌륭한 답변이 있지만 아이들과 함께 하나의 텍스트 노드 만 처리합니다. 제 경우에는 모든 텍스트 노드에서 작업하고 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 이 작동합니다.


0

.prependTo ()를 찾고 있다고 생각합니다.

http://api.jquery.com/prependTo/

페이지에서 요소를 선택하고 다른 요소에 삽입 할 수도 있습니다.

$ ( 'h2'). prependTo ($ ( '. container'));

이 방법으로 선택한 요소가 다른 곳에 삽입되면 대상으로 이동됩니다 (복제되지 않음).

<div class="container">  
  <h2>Greetings</h2>
  <div class="inner">Hello</div>
  <div class="inner">Goodbye</div> 
</div>

그러나 대상 요소가 두 개 이상있는 경우 삽입 된 요소의 복제 된 복사본이 첫 번째 이후 각 대상에 대해 생성됩니다.


2
나는 그렇게 생각하지 않는다. OP가 새 텍스트를 추가하는 것이 아니라 텍스트를 변경하는 방법을 찾고있는 것 같습니다.
Matt Ball

0

간단한 대답 :

$("div").contents().filter(function(){ 
  return this.nodeType == 3; 
})[0].nodeValue = "The text you want to replace with"

0

Mark의 대답의 문제는 빈 텍스트 노드도 얻는 것입니다. jQuery 플러그인으로 솔루션 :

$.fn.textnodes = function () {
    return this.contents().filter(function (i,n) {
        return n.nodeType == 3 && n.textContent.trim() !== "";
    });
};

$("div").textnodes()[0] = "changed text";

0

이것은 오래된 질문이지만 다음과 같은 간단한 기능을 만들어 삶을 더 쉽게 만들 수 있습니다.

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

0

2019 vesrsion-짧고 간단한

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

설명

document.querySelector('#your-div-id') 부모 (텍스트를 변경하려는 요소)를 선택하는 데 사용됩니다.

.childNodes[0] 텍스트 노드를 선택

.nodeValue = 'new text' 텍스트 노드 값을 "새 텍스트"로 설정합니다.


이 답변은 아마도 Dean Martin의 의견에서 영감을 얻었습니다. 이 솔루션을 몇 년 동안 사용해 왔기 때문에 확실히 말할 수 없습니다. 어떤 사람들은 이것이 최선의 해결책이라는 사실보다 그것에 더 관심이 있기 때문에이 확률을 여기에 게시해야한다고 생각했습니다.


2
방금 2014 년 Dean Martin의 의견을 복사하고이를 2019 년 솔루션으로 주장했습니다. 또한 제 생각에는 좋은 가독성을 위해 나쁜 습관 인 jQuery와 일반 Javascript의 불필요한 조합을 사용하십시오. 마지막으로 솔루션 작동 방식에 대한 세부 정보를 입력하지 않았습니다. 가장 복잡하지는 않지만이 문제도 아니므로 배열 인덱스에 액세스하여 jQuery 객체에서 네이티브 DOM 노드를 가져 오는 것과 같은 추가 설명을 사용할 수있는이 글을 읽는 꽤 새로운 프로그래머 일 것입니다.
Mark Baijens

@MarkBaijens 나는 당신이 옳을 것이라고 생각합니다. Dean Martin의 코멘트는 몇 년 전에 내가이 스 니펫을 얻은 곳일 것입니다. 어쨌든 나는 그 이후로 그것을 사용하고 있으며 1 월에 개인 코드 저장소 (유용한 스크립트를 나열하는 곳)에서 복사했습니다. 더 자세한 설명을 추가하고 불필요한 jQuery를 제거했습니다.
Silver Ringvee

이것은 실제로 작동하는 가장 간단한 솔루션이며 사람들은 그것을 사용해야하지만 딘 마틴에게 크레딧을주지 않고 자신의 것으로 칭찬을받지는 않습니다. 또한이 경우 순수한 Vanilla JS 구현이 jQuery와 Vanilla JS를 혼합하는 것보다 낫다는 Mark Baijens의 의견에 동의합니다. 더 나은 가독성뿐만 아니라 jQuery로 인해 속도가 느려지므로 성능이 향상됩니다.
Miqi180

@ Miqi180-위에서 이미 말했듯이 이것이 가능합니다.이 솔루션을 처음 얻은 곳을 기억하지 못합니다. 나는 수년 동안 내 작업에서 그것을 사용하고 있습니다. 답변에 메모를 추가했습니다. 바라 건데, 그렇게 여기에 최고의 솔루션에 대한 상관 없어 당신 같은 사람을 도움이 :
실버 Ringvee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.