jQuery filter element by border color

Hello,

I’ve got a web page in Sharepoint that I have to edit, specifically I have to modify the content of certain lis on the page. However I can’t do the following:

  • Add classes or IDs to elements on the page
  • Use existing css classes or ids because the classes names are dynamically generated on run time and not predictable. The classes use randomly generated numbers that change and are applied on the fly.

So I’m somewhat hamstrung on how I can target DOM elements. I’m trying to target some lis that have a grey border on the top.

Here is some sample code:


<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="content-type" content="text/html" />
	<meta name="author" content="Pierre Lemoine" />
	<title>Untitled 1</title>
    <style>
    .borderGray {
        border-top: 1px solid #d8d8d8;
    }
    </style>
    <script language="javascript" type="text/javascript" src="/courier/Style Library/Scripts/jquery-1.6.4.min.js"></script>
</head>

<body>
<ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li class="borderGray">Item 3</li>
    <li>Item 4</li>
</ul>

<script lang="javascript">
setTimeout(function() {
    var commentCollection = $("li").filter(function(index){return $(this).css("border-top-color") == "#d8d8d8";});

    $(commentCollection).each(function(index) {
      alert(index + ': ' + $(this).text());
    });

    alert('code complete');

}, 3000);
</script>
</body>
</html>

The javascript at the bottom is trying to target only the lis which have a border-top which is grey (#d8d8d8). I’ve gone over the jquery code in detail and can’t find why this isn’t working for me. When I run the page in IE7, it returns the content of the third li which is “Item 3”. However if I run this in Firefox or chrome it doesn’t enter the loop.

It appears that the variable “commentCollection” is not properly finding the page elements. Any ideas? Thanks.

Just noticed a typo in my example. This

alert(index + ': ’ + $(this).text());

Should read

alert($(this).text());

Ok I’ve gotten a litte farther but I’m still stuck. Newer browsers return the RGB value of the color and not the hex value.

So instead of #d8d8d8 I get back 216, 216, 216. I tried targeting “216, 216, 216” but that didn’t work either. Any ideas?

ok well I figured it out, hopefully this will help someone else. After banging my head against a wall for many hours I came to the conclusion that jquery can NOT compare a color property using rgb. For example in IE 7 you can use this to see if a property has a sepcific color value:

$(this).css("border-top-color") == "#d8d8d8"

The code above in older browsers works great. Since newer browsers return colors in RGB you would assume the following would work:

$(this).css("border-top-color") ==rgb(216, 216, 216)

However it doesn’t. You apparently can’t select an element based on a color property in this way. I did find a function that read an rgb color value and converted it back into hex, that allowed me to compare against the hex number and run the code I wanted. So here’s my sample solution, I used conditional comments to add support for older IE versions:



<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="content-type" content="text/html" />
	<meta name="author" content="Pierre Lemoine" />
	<title>Untitled 1</title>
    <script>
    var ie8down = false;
    </script>

    <!-- if this is ie 8 or less... -->
    <!--[if lt IE 9]>
    <script>
        var ie8down = true;
    </script>
    <![endif]-->


    <style>
    .borderGray {
        border-top: 1px solid #d8d8d8;
    }
    </style>

    <script language="javascript" type="text/javascript" src="jquery-1.7.2.min.js"></script>

</head>

<body>
<ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li class="borderGray">Item 4</li>
</ul>



<script lang="javascript">


//Function to convert rgb format to a hex
// Newer browsers return the color value in rgb
// This returns the value to hex for comparison
// jQuery could not compare rgb values
function rgb2hex(rgb){
 rgb = rgb.match(/^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$/);
 return "#" +
  ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
  ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
  ("0" + parseInt(rgb[3],10).toString(16)).slice(-2);
}

setTimeout(function() {
    // Array of li elements that have a grey top border
    var commentCollection = [];
    $("li").each(function() {
            if (ie8down == true){
                var colorTemp = $(this).css("border-top-color");
            } else {
                var colorTemp = rgb2hex($(this).css("border-top-color"));
            }
           if(colorTemp == "#d8d8d8"){
                // Add this li to array
                commentCollection.push($(this));
            }
    });

    $(commentCollection).each(function(index) {
      alert("result: "+$(this).text());
    });
}, 2000);
</script>
</body>
</html>


It can work if you create an rgb function to do the job.


function rgb(r, g, b) {
    return '#' + r.toString(16) + g.toString(16) + b.toString(16);
}

Sweet thanks for that Paul. I ended up doing the same idea just backwards, I converted the returned value back to hex. (Your solution looks to be cleaner)