JQuery | изменить часть строки со ссылками

0

У меня есть следующий код:

<div class="TopMenu">
<h3>Create an Account</h3>
<h3>yup</h3>
<h3>lol</h3>
<a href="#">yo</a>
<ul>
    <li sytle="display:">
        <a href="#">start</a> or
         <a href="#">finish</a>

    </li>
</ul>

и я использую:

    $('.TopMenu li:contains("or")').each(function() {
     var text = $(this).text();
    $(this).text(text.replace('or', 'triple'));  
});

Он отлично работает, но ссылки не активны, как я могу это исправить?

Заранее большое спасибо.

Теги:

6 ответов

0
Лучший ответ

Измените .text() на .html()

$('.TopMenu li:contains("or")').each(function() {
  var text = $(this).html();
  $(this).html(text.replace('or', 'triple'));  
});

См. Скрипку

  • 0
    <a href="c-or-d.html">cake or death</a>
1

Здесь то, что ваш jQuery в основном переводится, когда он запускается:

text = this.textContent;
// text = "\n\t\tstart or\n\t\t finish\n\t\t\n";
text = text.replace('or','triple');
// text = "\n\t\tstart triple\n\t\t finish\n\t\t\n";
this.textContent = text;
// essentially, remove everything from 'this' and put a single text node there

Хорошо, это не большое объяснение XD. Дело в том, что установка textContent (или, в jQuery, вызов .text()) заменяет содержимое элемента этим текстом.

То, что вы хотите сделать, просто влияет на текстовые узлы. Я не знаю, как это сделать в jQuery, но здесь некоторые Vanilla JS:

function recurse(node) {
    var nodes = node.childNodes, l = nodes.length, i;
    for( i=0; i<l; i++) {
        if( nodes[i].nodeType == 1) recurse(node);
        else if( nodes[i].nodeType == 3) {
            nodes[i].nodeValue = nodes[i].nodeValue.replace(/\bor\b/g,'triple');
        }
    }
}
recurse(document.querySelector(".TopMenu"));

Обратите внимание, что замена, основанная на регулярном выражении, не позволит "скучно" стать "btripleing". Используйте Vanilla JS и его магические способности, иначе я буду вас обманывать!

0

Это более сложная задача. Вам нужно заменить текст в текстовых узлах (nodeType === 3), что может быть сделано с помощью contents() и each итерации:

$('.TopMenu li:contains("or")').contents().each(function() {
    if (this.nodeType === 3) {
        this.nodeValue = this.nodeValue.replace('or', 'triple');
    }
});

Все остальные подходы будут либо переписывать разметку в элементе <li> (удаление всех прикрепленных событий), либо просто удалить внутренние элементы.

Как обсуждалось в комментариях ниже, безупречным решением будет использование замены с регулярным выражением, то есть this.nodeValue.replace(/\bor\b/g, 'triple'), который будет соответствовать всем or как автономные слова, а не как части слов.

ДЕМО: http://jsfiddle.net/48E6M/

  • 0
    Так близко , но так далеко.
  • 0
    @NiettheDarkAbsol Да, \bor\b сделает работу в этом случае. Однако, если у ОП есть только текст or там, неважно.
Показать ещё 2 комментария
0

Вы должны нам .html() вместо .text(),

Как это:

$('.TopMenu li:contains("or")').each(function() {
 var text = $(this).html();
$(this).html(text('or', 'triple'));  
});

Вот живой пример: http://jsfiddle.net/7Mamj/

  • 1
    И что, мол, скажите, что бы вы сделали, если бы HTML был <a href="c-or-d.html">cake or death</a> ?
  • 0
    @NiettheDarkAbsol Все ответы на самом деле ужасны ...
Показать ещё 8 комментариев
0

Так как or является текстовым узлом, вы можете использовать .contents() вместе с .replaceWith():

$('.TopMenu li:contains("or")').each(function () {
    var text = $(this).text();
    $(this).contents().filter(function () {
        return this.nodeType === 3 && $.trim(this.nodeValue).length;
    }).replaceWith(' triple ');
});

Демо-версия скрипта

0

jsFiddle Demo

Выполняя это, вы помещаете якоря в текст. Вы должны перебирать дочерние узлы с соответствующими элементами и использовать их только в свой textContent, чтобы не изменять любые теги или атрибуты html.

$('.TopMenu li:contains("or")').each(function() {
 for(var i = 0; i < this.childNodes.length; i++){
    if(this.childNodes[i].nodeName != "#text") continue;
    this.childNodes[i].textContent = this.childNodes[i].textContent.replace(' or ', ' triple ');
 }
});
  • 0
    <a href="c-or-d.html">cake or death?</a>
  • 0
    @NiettheDarkAbsol - Это определенно не идеально, но это работает для точного примера: PI действительно одобрил ваш ответ, поскольку он полностью решает все проблемное пространство.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню