2013-09-03 2 views
1

Я работаю над простым подключаемым браузером, чтобы заменить одно слово другим, но с добавлением привязки для небольшой всплывающей подсказки/всплывающего окна. У меня это уже работает, но моя проблема в том, что если слово, которое нужно заменить, уже находится в привязке, тогда мой </a> закрывает уже открытый <a>.Замена условий текста на странице

Так что мне нужна помощь в том, как только заменить слово, если оно не находится в пределах открытого тега привязки. Следующее - это также убедиться, что целевое слово не находится в <input> или других неподходящих тегах.

Мой код:

var regex = new RegExp("\\b" + nativeWord + "\\b", "igm"); 
var body = $('body'); 

body.each(function() { 
    $(this).html(
     $(this).html().replace(regex, function() { 
      counter++; 
      if(counter > wordSwapLimit) { 
       return nativeWord; 
      } else { 
       return "<a class=\"tooltip\" href=\"#\">" + studyWord + "<span class=\"classic\">" + nativeWord + "</span></a>";    
      } 
     }) 
    ); 
}); 

Я подозревал, что я, возможно, придется написать более сложную RegExp, но это моя первая вылазка с ней таким образом, любые предложения будут высоко оценены!

Обновление У меня есть тестовая страница, с которой я работаю, чтобы посмотреть, как работает мой код. Это часть исходного HTML со страницы:

<p id="changeArea"> I <a href="http://www.chicken.com">love chicken but I hate</a> beef. </p> 

Но с кодом, показанным выше, и обмен «курицы» для «кипы», это получает изменено на:

<p id="changeArea"> I <a href="http://www.&lt;a class=" tooltip"="">kip<span class="classic">chicken</span></a>.com"&gt;love <a class="tooltip" href="#">kip<span class="classic">chicken</span></a> but I hate beef. </p> 

Если у меня есть нет привязок вокруг того, что я обмениваю, тогда он отлично работает, и я получаю подсказку всплывающего подсказки.

Еще раз спасибо за помощь!

Update 2 В соответствии с просьбой, вот «необработанные» примеры, что мой плагин может попадался при замене «курица» для «кипы»:

<p id="changeArea"> I <a href="http://www.chicken.com">love chicken but I hate</a> beef. </p> 
<p id="changeArea2"> Chickenpie? pie-chicken. </p> 

Что я надеюсь на это следующее :

<p id="changeArea"> I <a href="http://www.chicken.com">love chicken but I hate</a> beef. </p> 
<p id="changeArea2"> Chickenpie? pie-<a class="tooltip" href="#">kip<span class="classic">chicken</span></a>. </p> 

Как вы можете видеть в первой строке HTML-код остается один, как текст для слова, потому что она находится в пределах URL и так бы разорвать его, если моя подсказку якорь был поставлен в. Вторая строка игнорирует «chickenpie», потому что мне нужна только замена всего слова, как и в моем существующем регулярном выражении. «pie-chicken» все-таки поменялся. Эта строка обрабатывается правильно с помощью существующего кода.

Я буквально просто хочу добавить дополнительные правила в свой существующий код, который говорит: «Не заменяйте код и не заменяйте его, если он находится в теге с открытым якорем.

+0

Я не совсем понял - даже если вы находитесь в открытом теге привязки, вы открываете еще один, поэтому конечный тег должен быть в порядке ...? – sje397

+0

В настоящее время он закрывает якоря для URL-адресов, а также свопирует слово, если оно находится в пределах 'href ='. Я редактировал вопрос с примером проблемы, которую он вызывает. – booleanBoy

+0

Может привести простой пример того, что вы хотите? A перед (два примера) и после (те же два, но как вы хотите их) – Martijn

ответ

0

Поскольку вы находитесь в JavaScript, у вас уже есть доступ к DOM. Почему бы вам попробовать using Regexes ???

Просто перебирать текстовые узлы, игнорируя существующие ссылки:

(function(elem) { 
    var recurse = arguments.callee, nodes = elem.childNodes, l = nodes.length, i, t, 
     getLink = function() { 
      var a = document.createElement('a'), s = document.createElement('span'); 
      a.href = "#"; 
      a.className = "tooltip"; 
      a.appendChild(document.createTextNode(studyWord)); 
      s.className = "classic"; 
      s.appendChild(document.createTextNode(nativeWord)); 
      a.appendChild(s); 
      return a; 
     }; 
    for(i=0; i<l; i++) { 
     switch(nodes[i].nodeType) { 
     case 1: 
      // element - recurse, but not if already a link 
      if(nodes[i].nodeName != "A") recurse(nodes[i]); 
      break; 
     case 3: 
      // text node, look for keyword 
      t = nodes[i].nodeValue.search(new RegExp("\\b"+nativeWord+"\\b","i")); 
      if(t > -1) { 
       // found it! now to hack around... 
       t = nodes[i].splitText(t); 
       t.splitText(nativeWord.length); 
       t.parentNode.replaceChild(t,getLink()); 
      } 
      break; 
     } 
    } 
})(document.body); 

Обратите внимание: Этот подход использует Vanilla JS. Это зависит от вас, чтобы убедиться, что он запущен после страница загружена.Это может быть сделано либо путем:

  • Добавление атрибута в скрипт defer, если это внешний
  • Ввод скрипта непосредственно перед </body> (или, по крайней мере, после того, как весь контент, который вы хотите повлиять)
  • Обертка в обработчике window.onload, или даже $(function() {...}), поскольку вы уже используете jQuery.
Смежные вопросы