Regex для поиска html-возврата, но не фактический html-jQuery - PullRequest
4 голосов
/ 16 марта 2011

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

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

http://oscargodson.com/labs/help-viewer

http://oscargodson.com/labs/help-viewer/js/jquery.jhighlight.js

Введите что-то в поиске ... хорошо, обновите страницу, теперь введите, например, class или class=" или введите <a, вы заметитеон будет искать фактический HTML (как и ожидалось).Как я могу только искать в тексте?

Если я сделаю .text(), он испарит весь HTML, а то, что я получу, будет просто большим кусочком текста, но я все еще хочу HTML, поэтому я не будупотерять форматирование, ссылки, изображения и т. д. Я хочу, чтобы это работало как CMD / CTRL + F.

Вы бы использовали этот плагин, например:

$('article').jhighlight({find:'class'});

Чтобы удалить их:

.jhighlight('remove')

== ОБНОВЛЕНИЕ ==

Хотя идея Майка Самуэля, представленная ниже, на самом деле работает, она немного тяжелаядля этого плагина.Это в основном для клиента, желающего стереть плохие слова и / или символы MS Word во время «публикации» формы.Я ищу более легкое решение, есть идеи?

Ответы [ 5 ]

2 голосов
/ 23 марта 2011

Вы действительно не хотите использовать eval, связываться с innerHTML или анализировать разметку «вручную». На мой взгляд, лучший способ - иметь дело с текстовыми узлами напрямую и хранить кеш исходного HTML-кода, чтобы стереть блики. Быстрая перезапись, с комментариями:

(function($){
  $.fn.jhighlight = function(opt) {

    var options = $.extend($.fn.jhighlight.defaults, opt)
      , txtProp = this[0].textContent ? 'textContent' : 'innerText';

    if ($.trim(options.find.length) < 1) return this;

    return this.each(function(){

      var self = $(this);

      // use a cache to clear the highlights
      if (!self.data('htmlCache'))
        self.data('htmlCache', self.html());

      if(opt === 'remove'){
        return self.html( self.data('htmlCache') );
      }

     // create Tree Walker
     // https://developer.mozilla.org/en/DOM/treeWalker
     var walker = document.createTreeWalker(
          this, // walk only on target element
          NodeFilter.SHOW_TEXT,
          null,
          false
      );

      var node
        , matches
        , flags = 'g' + (!options.caseSensitive ? 'i' : '')
        , exp = new RegExp('('+options.find+')', flags) // capturing
        , expSplit = new RegExp(options.find, flags) // no capturing
        , highlights = [];

      // walk this wayy
      // and save matched nodes for later
      while(node = walker.nextNode()){
        if (matches = node.nodeValue.match(exp)){
          highlights.push([node, matches]);
        }
      }

      // must replace stuff after the walker is finished
      // otherwise replacing a node will halt the walker
      for(var nn=0,hln=highlights.length; nn<hln; nn++){

        var node = highlights[nn][0]
          , matches = highlights[nn][1]
          , parts = node.nodeValue.split(expSplit) // split on matches
          , frag = document.createDocumentFragment(); // temporary holder

        // add text + highlighted parts in between
        // like a .join() but with elements :)
        for(var i=0,ln=parts.length; i<ln; i++){

          // non-highlighted text
          if (parts[i].length)
            frag.appendChild(document.createTextNode(parts[i]));

          // highlighted text
          // skip last iteration
          if (i < ln-1){
            var h = document.createElement('span');
            h.className = options.className;
            h[txtProp] = matches[i];
            frag.appendChild(h);
          }
        }
        // replace the original text node
        node.parentNode.replaceChild(frag, node);
      };

    });
  };

 $.fn.jhighlight.defaults = {
    find:'',
    className:'jhighlight',
    color:'#FFF77B',
    caseSensitive:false,
    wrappingTag:'span'
 };

})(jQuery);

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

Вы можете увидеть код, работающий здесь: http://jsbin.com/anace5/2/

Вам также необходимо добавить display: block к вашим новым html-элементам, макет не работает в некоторых браузерах.

0 голосов
/ 22 марта 2011

Может быть что-то подобное может быть полезным

>+[^<]*?(s(<[\s\S]*?>)?e(<[\s\S]*?>)?e)[^>]*?<+

Первая часть >+[^<]*? находит > последнего предшествующего тега

Третья часть [^>]*?<+ находит < первого последующего тега

Посередине у нас есть (<[\s\S]*?>)? между символами нашей поисковой фразы (в данном случае - «видеть»).

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

0 голосов
/ 22 марта 2011

Посмотрите здесь: getElementsByTagName () эквивалент для textNodes .Вероятно, вы можете адаптировать одно из предложенных решений к вашим потребностям (т. Е. Перебирать все текстовые узлы, заменяя слова по мере необходимости - это не будет работать в таких случаях, как <tag>wo</tag>rd, но это лучше, чем ничего, я думаю).1004 *

0 голосов
/ 22 марта 2011

Полагаю, вы могли бы просто сделать:

$('#article :not(:has(*))').jhighlight({find : 'class'});

Так как он захватывает все конечные узлы в статье, ему потребуется действительный xhtml, то есть он будет соответствовать link в следующем примере:

<p>This is some paragraph content with a <a href="#">link</a></p>

Приложение обхода / выбора DOM может немного затормозить, так что это может быть полезно:

article_nodes = article_nodes || $('#article :not(:has(*))');
article_nodes.jhighlight({find : 'class'});
0 голосов
/ 17 марта 2011

В кодировщике кода javascript у меня была эта проблема. Я хотел найти текст, но сохранить теги.

Я начал с HTML и разложил его на две части.

  1. Текстовое содержание
  2. Пары (индекс в текстовом содержимом, где встречается тег, содержимое тега)

Так дано

Lorem <b>ipsum</b>

Я получаю

text = 'Lorem ipsum'
tags = [6, '<b>', 10, '</b>']

, который позволяет мне осуществлять поиск по тексту, а затем на основе индексов начала и конца результата генерировать HTML, включающий только теги (и только сбалансированные теги) в этом диапазоне.

...