views:

311

answers:

3

I have a simple jQuery function:

$('#selectable1 span').live('mousedown', function() {
        var ff = $(this).css("font-family");
        $("#family").val(ff);
});

When a span element is clicked (mousedown) an input (#family) gets its font family value. It works in FireFox but in Chrome it works only for font families composed from only one word. Georgia will work but Times New Roman will not.

You can see the code here:

http://jsfiddle.net/aLaGa/

or live at http://www.typefolly.com

What is wrong with this? Thanx

A: 

Font-family gives a list of comma separated values, not the font in use. It also may give the value in quotes. On your sample page, adding the line alert(ff) gives:

'Times New Roman'

Georgia

adage-script-1, adage-script-2

Eric
+7  A: 

Chrome wraps font families having multiple words with single quotes. So the value for font-family returned in Chrome is: 'Times New Roman' which does not match the value in the select list Times New Roman.

Considering all these browser variations, I think the best solution is to split apart the family names by comma, trim the single quote (if any) around each font name, and join them later. Use this sanitized value inside the select list.

$('#selectable1 span').live('mousedown', function() {
    var fontFamily = $(this).css('font-family');

    var fonts = fontFamily.split(',');
    var sanitizedFonts = $.map(fonts, function(name) {
        // trim single quotes around font name (if any) for Chrome/Safari
        // trim double quotes around font name (if any) for Firefox
        return name.trim().replace(/^['"]|['"]$/g, '');
    });

    $('#family').val(sanitizedFonts.join(', '));
});

See an example. The select list had to be changed to follow this consistent naming scheme for values:

fontName[, fontName]

This heavily relies on the fact that a font-name will not contain any commas, quoted or unquoted.

Anurag
hmmm, so I have to strip the returned value of comas
Mircea
+1, was just on my way to post this after editing the tags and fixing a typo. It's also worth noting that Chrome also inserts a space after the comma in comma-separated font families, so that's why clicking "Adage" doesn't work either.
Andy E
That's another good point @Andy, I missed that.
Anurag
Thanx Anurag. This is also a great sollution
Mircea
Are there any font names that contain `,` within the quotes? If so, you've got a corner case to cover.
Eric
The names can be outside quotes as well as long as they are escaped. `font-family: "My, Awesome Font"` and `font-family: My\,Awesome\ Font` are both legal. Chrome will quote the second one when accessed through DOM, Firefox will simply return what was passed in which is a problem as we get back `My, Awesome Font` and there is no way to tell if `My` is a separate font. However, ignoring this impossible to deal with situation, we will need to write a little parser to ignore commas inside quoted strings :)
Anurag
+2  A: 

You can change your script slightly to replace the quotes that WebKit adds when the font name contains spaces, like this:

$('#selectable1 span').live('mousedown', function() {
  var ff = $(this).css("font-family").replace(/\'/g,"");
  $("#family").val(ff);
});    ​

You can see a working demo here :)

And here's a RegEx approach pulling the literal value out of style that's probably easier than anything, but I'm not a RegEx guru, someone feel free to improve this and update the answer (I suck at RegEx, sorry!) This works for all examples you have.

Nick Craver
@Nick: Although this will work for 'Times New Roman', the fix will need to go as far as changing the values of the select box too and actually fixing the way the CSS values are specified for full browser compatibility. You can see this even in your working demo :-)
Andy E
Thanx Nick, when you click on Adage it dose not work...
Mircea
@Andy - Clarify a bit? you can apply the version without quotes, it'll work, let me add to the demo.
Nick Craver
@Mircea, @Nick: See my comment reply to [Anurag's answer](http://stackoverflow.com/questions/2920147/jquery-val-not-working-properly-in-chrome/2920185#2920185). Chrome also inserts spaces after any commas in `font-family` which breaks Adage.
Andy E
@Mircea - You're going to have a pick a format in your `<select>` to fix this, you either have to have quotes on spaced ones or not to keep this simple, which do you prefer? Currently single ones don't have quotes, but multiple with a comma do.
Nick Craver
Probably it would be better without quotes...
Mircea
@Mircea - RegEx is *not* my thing, so hopefully someone can clean this up, but this approach should work: http://jsfiddle.net/aLaGa/13/
Nick Craver
Thanx Nick, this works. I was going for an "if" solution but this is much better
Mircea