4

I am trying to define a JQuery statement for finding elements which have a greater (or lesser respectively) font-size than an input value.

Possible input values:

"12px"
"14pt"
"120%"
and so on...

My first approach is more of a draft because it cannot work this way. But maybe you have ideas how to achieve a solution. Here is what i have so far (the input value comes from elsewhere and is variable):

$('*').filter(function() {
    return $(this).css('font-size') > '12px';
})

Anyone?

Update

I was asked to explain why i would need something like this. I am writing an API using Selenium2 in Java, which is able to find elements and interact with them in an easier and more reliable way. This function will allow me to write code like browser.find().titleElements() which selects all h1, h2,... tags, but also elements which have a greater font-size than the average text on the page.

The framework will also provide functions to select elements which are visually close to each other or in a specific direction:

HtmlElement nameLabel = browser.find().labelElement("name");
HtmlElement nameInput = browser.find().closestInputElement(nameLabel);
nameInput.below("tos").select();
Alp
  • 29,274
  • 27
  • 120
  • 198
  • 1
    That will be very tricky with relative font-sizing. Crescent Fresh's response to this Q: http://stackoverflow.com/questions/1313995/how-can-i-get-the-font-size-of-an-element-as-it-was-set-by-css details how jQuery always returns pixel values for font-size. So with jQuery, I think you'd need a way to get your pt, em, pct, etc input types converted to pixels, which I can't even imagine. As that answer points out, there might be an IE-only, non-jQuery way to do it. – Faust May 23 '11 at 10:28

3 Answers3

4

I made a small plugin that's able to take all the parameters you ask for. No idea how accurate it is since I made it in a rush. pt will definately be off if your DPI is anything other than 72.

Plugin code

(function($){
    $.fn.filterByFontSize = function(size){
        // Local scope vars
        var relative = false,
            matches = size
                .toString()
                .match(/^\d+(?:\.\d+)?(pt|em|%)$/i);

        // Parse size
        size = parseFloat(size, 10);

        // Check matches
        if (matches !== null) {
            switch (matches[1]) { 
                case "pt":
                    size = size*96/72;
                break;
                case "em":
                    relative = true;
                break;
                case "%":
                    relative = true;
                    size = (size/100)+0.01;
                break;
            }
        }

        // Filter elements accordingly
        return this.filter(function(){
            var $this = $(this),
                thisSize = parseInt(
                    $this.css("font-size"), 10);
            if (relative) {
                var parent = $this.parent();
                if (parent[0] === document) {
                    parent =  $(document.body);
                }
                var parentSize = parseInt(
                        parent.css("font-size"), 10);
                return parentSize*size < thisSize;
            } else {
                return thisSize > size;
            }
        });

    };
})(jQuery);

Usage

var bigTextElements = $("h1,h2,h3,p").filterByFontSize("24px");

You can try it out in this test case on jsFiddle.

Additional credits to converter for helping out with the optimization.

Community
  • 1
  • 1
mekwall
  • 28,614
  • 6
  • 75
  • 77
  • 1
    Why not use a simpler regex? `/^(\d+)(pt|em|%)$/i` - then you only need to check if `matches[2] == 'pt'` or `matches[2] == 'em'`, etc. – configurator May 23 '11 at 11:48
  • @configurator, yup. I was certain that it could be optimized. I'm no regex-wiz at all. Thanks, I'll change it! ;) – mekwall May 23 '11 at 11:51
  • 1
    I've refactored your code a bit - removed redundancy, made it a bit clearer IMO. Take a look: http://pastebin.com/EZ94bG3f – configurator May 23 '11 at 11:59
  • @configurator, very nice! You gotta add support for decimals in the regex though. Otherwise that's more or less perfect :) – mekwall May 23 '11 at 12:16
  • Thanks to both of you. I updated my question to explain the purpose of it. – Alp May 23 '11 at 12:43
  • @configurator & @Alp I've updated my test case with an optimized version! – mekwall May 23 '11 at 13:22
  • Great. Appreciate your solution, it's very neat. – Alp May 23 '11 at 14:48
1

you need to parse the font size...

try this way..

$('*').filter(function() {
    return parseInt($(this).css('font-size')) > '12px';
})
Vivek
  • 10,978
  • 14
  • 48
  • 66
0

You can use parseint so something like this:

function greaterThan(e, size = 12) {
    if (parseInt(e.css('font-size')) > size) {
        return true;
    }
    return false;
}

and call it like this:

var isBigger = greaterThan($(this));
udjamaflip
  • 682
  • 1
  • 8
  • 24