Выделите текст внутри HTML с помощью jQuery - PullRequest
10 голосов
/ 07 февраля 2012

Я собираюсь сделать что-то похожее на этот плагин http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html

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

если вы ищете my text

внутри html, например

this is <a href="#">my</a> text that needs highlighting

Вы не получите никакого выделения.

Есть ли способ выделить текст, игнорируя любой htmlметки между?

Ответы [ 3 ]

7 голосов
/ 07 февраля 2012

Я поиграл с некоторыми RegEx, которые позволяют использовать теги HTML в позиции пробельных символов:

<div id="test">this is <a href="#">my</a> text that needs highlighting</div>

JavaScript:

var src_str = $("#test").html();
var term = "my text";
term = term.replace(/(\s+)/,"(<[^>]+>)*$1(<[^>]+>)*");
var pattern = new RegExp("("+term+")", "i");

src_str = src_str.replace(pattern, "<mark>$1</mark>");
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"$1</mark>$2<mark>$4");

$("#test").html(src_str);

Попробуйте здесь: http://jsfiddle.net/UPs3V/

2 голосов
/ 19 октября 2012

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

<img src="brown fox.jpg" title="The brown fox" /><p>some text containing fox.</p>

сломает тег img:

var term = "fox";
term = term.replace(/(\s+)/,"(<[^>]+>)*$1(<[^>]+>)*");
var pattern = new RegExp("("+term+")", "i");
src_str ='<img src="brown fox.jpg" title="The brown fox" />'
    +'<p>some text containing fox.</p>'
src_str = src_str.replace(pattern, "<mark>$1</mark>");
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"$1</mark>$2<mark>$4");
src_str

Я работал над сценарием выделения и решил, что проблема, не реализующая сценарий, можетдолжны выделить несколько тегов.Вот как я понял, чтобы не уничтожать теги, пытаясь выделить контент внутри тегов, этот скрипт также выделяет несколько экземпляров внутри контента, но не над несколькими тегами:

str='<img src="brown fox.jpg" title="The brown fox" />'
    +'<p>some text containing fox. And onother fox.</p>'
var word="fox";
word="(\\b"+ 
    word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
        + "\\b)";
var r = new RegExp(word,"igm")
str.replace(/(>[^<]+)/igm,function(a){
    return a.replace(r,"<span class='hl'>$1</span>");
})

Не уверен, как объединить эти сценарии исделать подсветку нескольких тегов, но буду следить за этой темой.

1 голос
/ 23 июля 2013

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

Это достаточно простодобавьте параметры обратно и используйте классы, если хотите.

function highlight(re, node, depth, maxdepth){
    node = node || document.body;
    depth = depth || 0;
    maxdepth = maxdepth || 10;

    if( node.nodeType === 3 ){
        var match = node.data.match(re);
        if(match){
            var span = document.createElement('span');
            span.style.backgroundColor = '#ffa';
            var wordNode = node.splitText(match.index);
            wordNode.splitText(match[0].length);
            var wordClone = wordNode.cloneNode(true);
            span.appendChild(wordClone);
            wordNode.parentNode.replaceChild(span, wordNode);
            return 1;
        }
    } else if( depth === maxdepth ){
        console.log( 'Reached max recursion depth!', node );
    } else if( (node.nodeType === 1 && node.childNodes) && !/(script|style)/i.test(node.tagName) ) {
        for( var i = 0; i < node.childNodes.length; i++ ){
            i += highlight(re, node.childNodes[i], depth + 1, maxdepth);
        }
    }
    return 0;
}
...