Перечисление URL-адресов @font-face с помощью Javascript/JQuery


Существует ли способ перечисления всех URL-адресов @font-face (URL-адресов веб-шрифтов) данной HTML-страницы с помощью JavaScript или JQuery?

3 5

3 ответа:

Да, предполагая, что вы хотите найти все @ font-faces, указанные в таблице стилей, а не фактически используемые в самом HTML-документе.

Дана достаточно стандартная таблица стилей, которая выглядит следующим образом:

@font-face {
    font-family: 'Lobster12Regular';
    src: url('fonts/lobster_1.2-webfont.eot');
    src: url('fonts/lobster_1.2-webfont.eot?#iefix') format('embedded-opentype'),
         url('fonts/lobster_1.2-webfont.woff') format('woff'),
         url('fonts/lobster_1.2-webfont.ttf') format('truetype'),
         url('fonts/lobster_1.2-webfont.svg#Lobster12Regular') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'AllerRegular';
    src: url('fonts/aller_std_rg-webfont.eot');
    src: url('fonts/aller_std_rg-webfont.eot?#iefix') format('embedded-opentype'),
         url('fonts/aller_std_rg-webfont.woff') format('woff'),
         url('fonts/aller_std_rg-webfont.ttf') format('truetype'),
         url('fonts/aller_std_rg-webfont.svg#AllerRegular') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'AllerBold';
    src: url('fonts/aller_std_bd-webfont.eot');
    src: url('fonts/aller_std_bd-webfont.eot?#iefix') format('embedded-opentype'),
         url('fonts/aller_std_bd-webfont.woff') format('woff'),
         url('fonts/aller_std_bd-webfont.ttf') format('truetype'),
         url('fonts/aller_std_bd-webfont.svg#AllerBold') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'AllerLight';
    src: url('fonts/aller_std_lt-webfont.eot');
    src: url('fonts/aller_std_lt-webfont.eot?#iefix') format('embedded-opentype'),
         url('fonts/aller_std_lt-webfont.woff') format('woff'),
         url('fonts/aller_std_lt-webfont.ttf') format('truetype'),
         url('fonts/aller_std_lt-webfont.svg#AllerLight') format('svg');
    font-weight: normal;
    font-style: normal;

}

h1 {
    font-family: 'Lobster12Regular';
}

h2 {
    font-family: 'AllerRegular';
}

Тогда следующий HTML (со встроенным Javascript) будет более или менее делать трюк:

<html>

<head>

<link rel="stylesheet" href="test.css">

</head>

<body>

<h1>Hello</h1>
<h2>Hello</h2>

<script type="text/javascript">

var pattern=/url\(.*?\)/g;
for (var i=0;i<document.styleSheets[0].cssRules.length;i++)
{
    var urls=document.styleSheets[0].cssRules[i].cssText.match(pattern);
    if (urls)
    {
        for (var j=0;j<urls.length;j++)
        {
            alert(urls[j]);
        }
    }
}

</script>

</body>

</html>

С некоторыми оговорками:

Во-первых, один из основных способов указать @font-face основан на указании src дважды, этот метод будет только подбирать второй src.

Я не тестировал этот кросс-браузер, но он работает в моем браузере и всплывает окно предупреждения с каждым url-адресом шрифта.

Жестко закодированный [0] заставляет его смотреть только на первую таблицу стилей (в этом примере есть только одна). Это достаточно тривиально, чтобы написать еще один цикл для цикла по всем таблицам стилей, если это необходимо, но казалось излишним для этого примера.

Нет, не совсем. Есть только, кажется, эта техника: http://paulirish.com/2009/font-face-feature-detection/ для определения, можно ли использовать @font-face, но не для определения, какие шрифты используются. За исключением анализа всего кода CSS на стороне сервера (или, по крайней мере, на стороне сервера), нет никакого способа сделать то, что вы хотите, не только с помощью JS и jQuery. Сожалеть об этом.

Это то, что я только что написал для собственного использования, прекрасно работает с Chrome, не тестировался с другими браузерами - но кажется мне довольно стандартным.

Он требует jquery, и будет идентифицировать все используемые шрифты и их источники (если webfonts).

Обратите внимание, что он не может адекватно обрабатывать вариации шрифта (разные "полужирные" версии), а также не может обрабатывать стили с несколькими определенными шрифтами (например: font-family: fonta, fontb, fontc).

jQuery.fn.elementText = function() {
    return $(this)  
            .clone()
            .children()
            .remove()
            .end()
            .text()
            .replace(/^\s\s*/, '').replace(/\s\s*$/, '')
            ;
};

Font = function(family, src) {
    // In order to properly categorise complex font setups, weight and style need to be 
    // considered as part of a unique font. (TODO)
    this.family = family;
    this.src = src;
    this.weight = null;
    this.style = null;
};

Font.prototype.toString = function() {
    return '[Font ' + this.family + ': ' + this.src + ']';
};


var fontNames = {};
var fontObjects = [];

$(':visible').each(function (k, v) {
    var $v = $(v);
    var font;
    if ($v.elementText().length) {
        font = $v.css('font-family');
        // TODO: seperate by comma, remove quotes
        fontNames[font] = font;
    }
});

for (var sheet=0; sheet < document.styleSheets.length; sheet++)
for (var i=0; i<document.styleSheets[sheet].cssRules.length; i++)
{
    var rule = document.styleSheets[sheet].cssRules[i];
    if (rule instanceof CSSFontFaceRule) {
        if (fontNames[rule.style.fontFamily])
            fontObjects.push(
                    new Font(rule.style.fontFamily, rule.style.src) );
    }
}

fontObjects.forEach( function(v) { console.log(v.toString()); });

Пример вывода (здесь вы можете увидеть пример того, что происходит, когда у вас есть разные 'bold', 'italic' и т. д. определяет стиль шрифта):

[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-BookItalic.otf)]
[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-Book.otf)]
[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-MediumItalic.otf)]
[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-Medium.otf)]
[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-BoldItalic.otf)]
[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-Bold.otf)]
[Font 'ITC Legacy Sans Std': url(http://localhost/~admin/tmp/fonts/LegacySansStd-Ultra.otf)]
[Font 'Ocean Sans Std': url(http://localhost/~admin/tmp/fonts/OceanSansStd-LightIta.otf)]
[Font 'Ocean Sans Std': url(http://localhost/~admin/tmp/fonts/OceanSansStd-Light.otf)]
[Font 'Ocean Sans Std': url(http://localhost/~admin/tmp/fonts/OceanSansStd-Book.otf)]
[Font 'Ocean Sans Std': url(http://localhost/~admin/tmp/fonts/OceanSansStd-SemiboldIta.otf)]
[Font 'Ocean Sans Std': url(http://localhost/~admin/tmp/fonts/OceanSansStd-Semibold.otf)]
[Font 'Ocean Sans Std': url(http://localhost/~admin/tmp/fonts/OceanSansStd-Bold.otf)]