Я использую фильтр следующим образом
$("body div header").find("*").addBack().contents().filter(function(){
console.log(this.nodeType);
return this.nodeType === 3;
}).each(function() {
$(this).parent().html(this.nodeValue.replace(/abc/g, '<span class="abc">abc</span>'));
})
Но это не работает, поскольку он не добавляет класс к совпадающим словам. http://jsfiddle.net/hrEyC/3/
Что может быть неправильным? Как я могу сделать это без учета регистра?
Очевидно, что в вашей разметке нет header
, поэтому самый первый объект jQuery, который вы пытаетесь обработать, пуст.
Тем не менее, весь подход немного неправильный: разные текстовые узлы будут иметь тот же узел, что и родительский, но вы в основном переписываете этот узел innerHTML каждый раз. На самом деле, поскольку большинство текстовых узлов первого ребенка в этом примере имеют '\n '
аромат, все остальные не имеют значения - они исчезнут после первого соответствующего $(this).parent().html()
вызов.
То, что вы на самом деле должны использовать, - это метод replaceWith jQuery. Например:
$("body div").find("*").addBack().contents().filter(function(){
return this.nodeType === 3 && /abc/i.test(this.nodeValue);
}).replaceWith(function() {
return this.nodeValue.replace(/(abc)/g, '<span class="abc">$1</span>');
});
Демо. Здесь я подрезал список узлов, которые нужно обрабатывать с помощью replaceWith
дополнительно (с помощью /abc/.test(...)
) - чтобы сделать этот список максимально тонким.
Чтобы сделать этот поиск нечувствительным к регистру, я добавил модификатор /i
к обоим регулярным выражениям (и использовал $1
в заменяющей строке, а также - вы не хотите, чтобы "ABC" стала "abc" при подсвечивании).