2011-06-10 2 views
0

Как вы выделяете (или придаете специальную разметку) специальные символы, такие как ‘’“”‛‟′″˝? Благодарю. Использование find и replace .innerHTML.replace() не работает, поскольку оно разрушает обработчики событий и DOM.javascript подсветка символов


Я попытался следующие, но это только заканчивается с span-х в виде обычного текста вместо кода.

function highlightText(node, find, rep){ 
    if(node){ 
     node= node.firstChild; 
     while(node!= null){ 
      if(node.nodeType== 3){ 
       node.data= node.data.replace(find, rep); 
      } 
      else highlightText(node, find, rep); 
      node= node.nextSibling; 
     } 
    } 
    return true; 
} 

highlightText(document.body,/‘/g, "<span style='background: red; color: white;'>‘</span>") 
highlightText(document.body,/’/g, "<span style='background: red; color: white;'>’</span>") 
highlightText(document.body,/“/g, "<span style='background: red; color: white;'>“</span>") 
highlightText(document.body,/”/g, "<span style='background: red; color: white;'>”</span>") 
highlightText(document.body,/‛/g, "<span style='background: red; color: white;'>‛</span>") 
highlightText(document.body,/‟/g, "<span style='background: red; color: white;'>‟</span>") 
highlightText(document.body,/′/g, "<span style='background: red; color: white;'>′</span>") 
highlightText(document.body,/″/g, "<span style='background: red; color: white;'>″</span>") 
highlightText(document.body,/˝/g, "<span style='background: red; color: white;'>˝</span>") 

ответ

2

Вот код, который работает во всех основных браузерах.Я опубликовал варианты этого кода в Stack Overflow (here, here и here, например), и сделал его приятным и универсальным, поэтому мне (или кому-либо еще) не нужно его много менять, чтобы повторно использовать его.

jsFiddle пример: http://jsfiddle.net/eh8FE/

Код:

// Reusable generic function 
function surroundInElement(el, regex, surrounderCreateFunc) { 
    // script and style elements are left alone 
    if (!/^(script|style)$/.test(el.tagName)) { 
     var child = el.lastChild; 
     while (child) { 
      if (child.nodeType == 1) { 
       surroundInElement(child, regex, surrounderCreateFunc); 
      } else if (child.nodeType == 3) { 
       surroundMatchingText(child, regex, surrounderCreateFunc); 
      } 
      child = child.previousSibling; 
     } 
    } 
} 

// Reusable generic function 
function surroundMatchingText(textNode, regex, surrounderCreateFunc) { 
    var parent = textNode.parentNode; 
    var result, surroundingNode, matchedTextNode, matchLength, matchedText; 
    while (textNode && (result = regex.exec(textNode.data))) { 
     matchedTextNode = textNode.splitText(result.index); 
     matchedText = result[0]; 
     matchLength = matchedText.length; 
     textNode = (matchedTextNode.length > matchLength) ? 
      matchedTextNode.splitText(matchLength) : null; 
     surroundingNode = surrounderCreateFunc(matchedTextNode.cloneNode(true)); 
     parent.insertBefore(surroundingNode, matchedTextNode); 
     parent.removeChild(matchedTextNode); 
    } 
} 

// This function does the surrounding for every matched piece of text 
// and can be customized to do what you like 
function createSpan(matchedTextNode) { 
    var el = document.createElement("span"); 
    el.style.backgroundColor = "red"; 
    el.style.color = "white"; 
    el.appendChild(matchedTextNode); 
    return el; 
} 

// The main function 
function wrapSpecialChars(container) { 
    surroundInElement(container, /[‘’“”‛‟′″˝]+/, createSpan); 
} 

wrapSpecialChars(document.body); 
1

Единственный способ изменить форматирование любого текста в HTML - это определить стиль элемента HTML, который окружает текст. Итак, если вы хотите выделить только определенные символы, эти символы должны быть обернуты элементом HTML, обычно span, хотя вы можете быть более семантичным.

Итак, я не уверен, что вы подразумеваете под «руинами обработчиков событий и DOM», но вам нужно будет изменить DOM, чтобы выделить символы. Об этом нет.

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


Если вы действительно хотите, чтобы выделить некоторые символы через всю страницу, вы должны сделать это неразрушающим:

  1. Создайте функцию, которая работает рекурсивно
  2. перебрать все дочерние узлы узел, взятый в качестве параметра
  3. Если узел является элементом, вызовите self-recursively с новым узлом
  4. Если узел является текстовым узлом, замените этот текстовый узел на HTML, wrappi ng символов в диапазоне, который вы хотите.
  5. Вызовите вышеуказанную функцию корневым узлом содержимого, которое вы хотите заменить.
+0

Это не так, например, '.innerHTML.replace()' может заменить любое случайное слово на странице (включая добавление 'span') без необходимости изменять HTML-страницу, которая просто недоступна. Но это нарушает остальную часть страницы, уничтожая DOM и все обработчики событий. Должен быть хороший способ сделать это. – user793238

+0

@ user793238 Так что это не так? Я не думаю, что это противоречит сказанному мной. Я сказал, что установка innerHTML заменит все узлы в этой части дерева. – Nicole

+0

@Renesis вы сказали, что символы должны быть завернуты в «span», прежде чем это можно было бы сделать, что неверно. Вы можете сделать это, даже если это не так, но это уничтожает DOM и все обработчики событий. Не уверен, что вы просите, чтобы вы могли помочь. – user793238

-1

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

Например, вы можете изменить стили объектов, чтобы выделить, когда страница загружена. Здесь есть основная идея.

<body onload='highlight()'> 
... 
</body> 

где

function highlightSpan(content) 
{ 
    return "<span style='background: yellow'>" + content + "</span>"; 
} 

function hightlight() 
{ 
    var highlightChars = "‘’“”‛‟′″˝"; 
    // change body content (and highlight chars) 

    var bodyContent = $("body").html(); 

    for(var i = 0; i < highlightChars.length; i++) 
    { 
    var highlightChar = highlightChars[ i ]; 
    bodyContent = bodyContent.replace(highlightChar, highlightSpan(highlightChar)); 
    } 

    $("body").html(bodyContent); 

} 

Вы можете использовать document.getElementsByTagName ("тело") [0] .innerHTML вместо $ ("тело") .html().

Может быть заменить() заменит только один соответствующий первый символ. Таким образом, вы можете использовать replace (/ ('|' | "|" | '| "|' |")/g, highlightSpan (что-то));. И решить проблему с ~, который является особым регулярным выражением.

+0

Но лучше, когда бэкэнд формирует вывод с выделенными символами. – sergzach

+0

Проблема с этим - все DOM удаляется и заменяется новыми узлами. ОП упомянул, что это проблема, которую он или она хотел избежать в первую очередь. – Nicole

+0

Вы правы! Спасибо. – sergzach

Смежные вопросы