Заменить строку, когда она соответствует ключу в паре ключ / значение (с соответствующим значением) - PullRequest
4 голосов
/ 11 августа 2011

Я пытаюсь использовать javascript / jQuery для переноса любых сокращений в абзаце в тег * <abbr title="">.

Например, в таком предложении, как ВОЗ eLENA разъясняет руководство по жизненно важным вмешательствам в области питания и помогает расширить масштабы действий по борьбе с недоеданием, WHO и eLENA будут обабыть завернутым в тег <abbr>.Мне бы хотелось, чтобы атрибут title отображал расширенную версию аббревиатуры;то есть WHO = World Health Organization.

Каков наилучший способ сделать это?Я немного новичок в javascript / jQuery, поэтому я играю здесь в темноте.До сих пор я создал переменную, которая содержит все сокращения в виде пар ключ / значение, и я могу заменить конкретный экземпляр сокращения, но не более того.

Ответы [ 3 ]

1 голос
/ 11 августа 2011

Во-первых, это действительно нужно делать на сервере, делать это на клиенте очень неэффективно и гораздо более подвержено ошибкам.Но сказав, что ...

Вы можете попробовать обработать 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 .

1 голос
/ 11 августа 2011

Сначала вы должны решить, какие именно критерии вы будете использовать для выбора замены - я бы предложил сделать это на границе слова, чтобы слово «Я работаю с ВОЗ» обернуло «ВОЗ» в аббревиатуру, но «КТО ТРЕБУЕТСЯМОЙ ВЕЛОСИПЕД СДЕЛАЕТ ЕГО "не будет сокращать" ВОЗ ".Вы также должны решить, будете ли вы учитывать регистр (вероятно, вы хотите, чтобы он, так что «Парень, который только что вошел», не сокращает «кто».)

  1. Используйте jQuery длязачеркните весь текст в документе.Это можно сделать с помощью селектора .children, пошагово просматривая элементы и читая весь текст.
  2. Для каждого текстового узла разбейте текст на слова.
  3. Для каждого слова найдите егов вашем хранилище значений ключей, чтобы увидеть, соответствует ли он ключу.Если это так, получите значение и создайте новый элемент <abbr title="value">key</abbr>.
  4. Разбейте текстовый узел на а) текст перед аббревиатурой (текстовый узел), б) собственно аббревиатуру (элемент)и в) текст после сокращения (текстовый узел).Вставьте все три как дочерние узлы исходного родительского текстового узла, заменив исходный текстовый узел.

Каждый из этих шагов потребует немного работы и поиска некоторых документов API, но это основнойпроцесс.

0 голосов
/ 11 августа 2011

Проверьте javascript метод замены .

Я бы использовал JQuery, чтобы вытащить весь текст в абзаце

var text = $(p#paragraphId).html()

Используйте цикл for для циклического просмотра списка имеющихся у вас сокращений, а затем используйте метод replace (), упомянутый выше, чтобы поменять сокращение на нужный вам тег.

Наконец, используйте JQuery, чтобы установить html-абзац обратно в только что обновленную строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...