4

This answer works almost perfectly for my needs. The problem is that it will also match URL values in the href attribute of an a tag. So If I have:

<a href="/a-link-to-a-porsche-page">This is a link to a porsche page</a>

and use this selector:

$("a").highlight("porsche", "highlighted");

porsche gets matched in both the url and the link text. What can be done so that values of the href attribute are omitted?

Previously referenced answer for posterity:

jQuery.fn.highlight = function (str, className) {
    var regex = new RegExp(str, "gi");

    return this.each(function () {
        this.innerHTML = this.innerHTML.replace(regex, function(matched) {return "<span class=\"" + className + "\">" + matched + "</span>";});
    });
};

Didn't know about jsfiddle. Here's a more complete example based on justkt's response: http://jsfiddle.net/Dzejms/L5Knh/1/

Community
  • 1
  • 1
Dzejms
  • 3,108
  • 2
  • 30
  • 40
  • I don't see anything wrong with your solution. Everything seems to work as expected. See my jsfiddle. http://jsfiddle.net/k6VYC/1/ –  Apr 04 '11 at 18:38
  • 1
    I'm not seeing the problem when `a` is the selector. See [here](http://jsfiddle.net/DRvqs/). I can understand if the link tag is wrapped in a div which is the selector, etc, like [this](http://jsfiddle.net/DRvqs/1/) – justkt Apr 04 '11 at 18:38
  • updated question with jsfiddle link http://jsfiddle.net/Dzejms/L5Knh/1/ – Dzejms Apr 04 '11 at 19:35

2 Answers2

5

------edit------

a cursory search on google turned up this neat jquery plugin. the idea is the same as what is the other answer, but it uses recursion and regex to make it more efficient. check it out.

nathan gonzalez
  • 11,817
  • 4
  • 41
  • 57
  • @justkt, true enough. i suppose it depends on the use case. – nathan gonzalez Apr 04 '11 at 18:41
  • Try taking a look at `textContent` (Firefox + most browsers) and `innerText` (IE + a few browsers). They differ in terms of whitespace, but you should still be able to search them once you strip out things like newlines. –  Apr 04 '11 at 18:49
2

One option is to drill down to the children of each object to make sure that you aren't grabbing the DOM nodes in your innerHTML.

Here is a fairly inefficient example that uses recursion on the children of each matched object:

jQuery.fn.highlight = function (str, className) {
    var regex = new RegExp(str, "gi");

    return this.each(function () {
        checkHighlight(this);
    });

    function checkHighlight(obj) {
        var children = $(obj).children();
        if(children.length == 0) {
            doHighlight(obj);
        } else {
            children.each(function() {
                checkHighlight(this);
            });
        }
    }

    function doHighlight(obj) {
        obj.innerHTML = obj.innerHTML.replace(regex, function(matched) {return "<span class=\"" + className + "\">" + matched + "</span>";});
    }
};

See it in action here.

justkt
  • 14,610
  • 8
  • 42
  • 62
  • Close. Here's a more real world example of what I'm dealing with: http://jsfiddle.net/Dzejms/L5Knh/1/ – Dzejms Apr 04 '11 at 19:24
  • @Dzejms - My earlier version [seems to work](http://jsfiddle.net/L5Knh/2/). The only thing it isn't doing is highlighting the alt attribute shown where the broken image is. – justkt Apr 04 '11 at 19:36
  • i do like this better than mine, since it works in all situations. there has to be a way to do this more efficiently though. – nathan gonzalez Apr 04 '11 at 21:53