Во-первых, это действительно нужно делать на сервере, делать это на клиенте очень неэффективно и гораздо более подвержено ошибкам.Но сказав, что ...
Вы можете попробовать обработать innerHTML элемента, но JavaScript и регулярные выражения действительно плохи в этом.
Лучший способ - использовать методы DOM и анализировать текст каждого элемента.Когда найдено подходящее слово, замените его элементом abbr.Для этого необходимо, чтобы в случае совпадения в текстовом узле весь узел заменялся, поскольку то, что раньше было одним текстовым узлом, теперь будет двумя (или более) текстовыми узлами по обе стороны от элемента abbr.
Вотпростая функция, которая подходит близко, но, скорее всего, у нее есть недостатки, к которым вам нужно обратиться.Он работает с простыми текстовыми строками, но вам необходимо тщательно протестировать его на более сложных строках.Естественно, его следует запускать только один раз на определенном узле, иначе сокращения будут заключены в двойную оболочку.
var addAbbrHelp = (function() {
var abbrs = {
'WHO': 'World Health Organisation',
'NATO': 'North Atlantic Treaty Organisation'
};
return function(el) {
var node, nodes = el.childNodes;
var word, words;
var adding, text, frag;
var abbr, oAbbr = document.createElement('abbr');
var frag, oFrag = document.createDocumentFragment()
for (var i=0, iLen=nodes.length; i<iLen; i++) {
node = nodes[i];
if (node.nodeType == 3) { // if text node
words = node.data.split(/\b/);
adding = false;
text = '';
frag = oFrag.cloneNode(false);
for (var j=0, jLen=words.length; j<jLen; j++) {
word = words[j];
if (word in abbrs) {
adding = true;
// Add the text gathered so far
frag.appendChild(document.createTextNode(text));
text = '';
// Add the wrapped word
abbr = oAbbr.cloneNode(false);
abbr.title = abbrs[word];
abbr.appendChild(document.createTextNode(word));
frag.appendChild(abbr);
// Otherwise collect the words processed so far
} else {
text += word;
}
}
// If found some abbrs, replace the text
// Otherwise, do nothing
if (adding) {
frag.appendChild(document.createTextNode(text));
node.parentNode.replaceChild(frag, node);
}
// If found another element, add abbreviation help
// to its content too
} else if (node.nodeType == 1) {
addAbbrHelp(node);
}
}
}
}());
Для разметки:
<div id="d0">
<p>This is the WHO and NATO string.</p>
<p>Some non-NATO forces were involved.</p>
</div>
и вызова:
addAbbrHelp(document.getElementById('d0'));
приводит к (моему форматированию):
<div id="d0">
<p>This is the<abbr title="World Health Organisation">WHO</abbr>
and <abbr title="North Atlantic Treaty Organisation">NATO</abbr>
string.</p>
<p>Some non-<abbr title="North Atlantic Treaty Organisation">NATO</abbr> forces were involved.</p>
</div>
Использование шаблона разбиения по словам для разделения слов интересно, потому что в строках типа "с силами, не входящими в НАТО" слово НАТО будет по-прежнему переноситься, но не«не -» часть.Однако, если аббревиатура разделена по текстовому узлу или дефису, она не будет распознана, если тот же шаблон не включен в качестве имени свойства в объекте abbrs .