Как изменить текст внутри span с помощью jQuery, оставив остальными узлами span нетронутыми узлы? - PullRequest
4 голосов
/ 28 февраля 2012

У меня есть следующий фрагмент HTML:

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

Я бы хотел изменить текстовый узел (т. Е. «Измени меня») внутри диапазона из jQuery, оставив при этом вложенный тег <a> со всеми атрибутами и т. Д. Без изменений. Сначала я использовал .text(...) на узле span, но, как оказалось , получается , это заменит всю внутреннюю часть переданным текстовым содержимым.

Я решил эту проблему, сначала клонировав тег <a>, затем установив новое текстовое содержимое <span> (которое удалит исходный тег <a>), и, наконец, добавив клонированный тег <a> в мой <span>. Это работает, но чувствует себя таким излишним для такой простой задачи, как эта. Btw. Я не могу гарантировать, что внутри промежутка будет начальный текстовый узел - он может быть пустым, например:

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

Я тоже сделал jsfiddle . Итак, каков был бы аккуратный способ сделать это?

Ответы [ 8 ]

6 голосов
/ 28 февраля 2012

Попробуйте что-то вроде:

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

демо: http://jsfiddle.net/eEMGz/

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

Обновление :

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

$('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);
});

Демо: http://jsfiddle.net/eEMGz/3/

1 голос
/ 28 февраля 2012

Вы выходите из jQuery, потому что он не помогает вам работать с текстовыми узлами. Далее будет удален первый дочерний элемент каждого элемента <span> с классом «target», если и только если он существует и является текстовым узлом.

Демо: http://jsfiddle.net/yx5Ju/11/

Код:

$('span.target').each(function() {
    var firstChild = this.firstChild;
    if (firstChild && firstChild.nodeType == 3) {
        firstChild.data = "Do it again";
    }
});
1 голос
/ 28 февраля 2012

Вы можете попробовать это.

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');
    }
});

Рабочая демонстрация - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/

1 голос
/ 28 февраля 2012

Вы можете использовать .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);
        }
    });
});​

Вот демоверсия: http://jsfiddle.net/jasper/PURHA/1/

Некоторые документы для тебя:

Обновление

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);
});​

Демо: http://jsfiddle.net/jasper/PURHA/2/

0 голосов
/ 28 февраля 2012
$('a.changeme').click(function() {                         
    var firstNode= $(this).parent().contents()[0];
        if( firstNode.nodeType==3){
        firstNode.nodeValue='New text';
    }
})

РЕДАКТИРОВАТЬ: не уверены, какие правила компоновки вам нужны, обновить для проверки только первого узла, в противном случае адаптировать при необходимости

0 голосов
/ 28 февраля 2012

Вы можете изменить собственное (не jquery) свойство данных объекта.Обновленный jsfiddle здесь: http://jsfiddle.net/elgreg/yx5Ju/2/

Что-то вроде:

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

Content () получает внутренности, а get (0) возвращает нас к исходному элементу, а .dataтеперь ссылка на нативный текстовый узел js.(Я не тестировал этот кросс-браузер.)

Этот jsfiddle и ответ на самом деле являются просто расширенным объяснением ответа на этот вопрос: Изменение текста текстовых узлов

0 голосов
/ 28 февраля 2012

Вы можете обернуть текст в промежуток ... но ...

попробуй это. http://jsfiddle.net/Y8tMk/

$(function(){
    var txt = '';
    $('.target').contents().each(function(){
        if(this.nodeType==3){
                    this.textContent = 'done ';
        }
    });
});
0 голосов
/ 28 февраля 2012

Я думаю, это не идеальный пример, но вы можете использовать функцию contents .

console.log($("span.target").contents()[0].data);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...