首页 > 解决方案 > 如何将 Google 字体链接更改为 css @import 以在本地获取字体

问题描述

我有一个工作代码,我在这里找到了elemon的 Google 字体选择器

它工作得很好,但是当我正在构建一个离线应用程序时,我需要从文件夹中加载字体。但是我在尝试中搞砸了。代码如下:

var FragBuilder = (function() {
    var applyStyles = function(element, style_object) {
        for (var prop in style_object) {
            element.style[prop] = style_object[prop];
        }
    };
    var generateFragmentFromJSON = function(json) {
        var tree = document.createDocumentFragment();
        json.forEach(function(obj) {
            if (!('tagName' in obj) && 'textContent' in obj) {
                tree.appendChild(document.createTextNode(obj['textContent']));
            } else if ('tagName' in obj) {
                var el = document.createElement(obj.tagName);
                delete obj.tagName;
                for (part in obj) {
                    var val = obj[part];
                    switch (part) {
                    case ('textContent'):
                        el.appendChild(document.createTextNode(val));
                        break;
                    case ('style'):
                        applyStyles(el, val);
                        break;
                    case ('childNodes'):
                        el.appendChild(generateFragmentFromJSON(val));
                        break;
                    default:
                        if (part in el) {
                            el[part] = val;
                        }
                        break;
                    }
                }
                tree.appendChild(el);
            } else {
                throw "Error: Malformed JSON Fragment";
            }
        });
        return tree;
    };
    var generateFragmentFromString = function(HTMLstring) {
        var div = document.createElement("div"),
            tree = document.createDocumentFragment();
        div.innerHTML = HTMLstring;
        while (div.hasChildNodes()) {
            tree.appendChild(div.firstChild);
        }
        return tree;
    };
    return function(fragment) {
        if (typeof fragment === 'string') {
            return generateFragmentFromString(fragment);
        } else {
            return generateFragmentFromJSON(fragment);
        }
    };
}());

function jsonp(url) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    document.getElementsByTagName('body')[0].appendChild(script);
}

function replacestyle(url) {
    if (!document.getElementById('style_tag')) {
        var style_tag = document.createElement('link');
        style_tag.rel = 'stylesheet';
        style_tag.id = 'style_tag';
        style_tag.type = 'text/css';
        document.getElementsByTagName('head')[0].appendChild(style_tag);
        replacestyle(url);
    }
    document.getElementById('style_tag').href = url;
}

function loadFonts(json) {
    var select_frag = [
        {
        'tagName': 'select',
        'id': 'font-selection',
        'childNodes': [
            {
            'tagName': 'option',
            'value': 'default',
            'textContent': 'Default'}
        ]}
    ];
    json['items'].forEach(function(item) {
        var family_name = item.family,
            value = family_name.replace(/ /g, '+');

        if (item.variants.length > 0) {
            item.variants.forEach(function(variant) {
                value += ':' + variant;
            });
        }

        select_frag[0].childNodes.push({
            'tagName': 'option',
            'value': value,
            'textContent': family_name
        });
    });

    document.getElementById('container').appendChild(FragBuilder(select_frag));
    document.getElementById('font-selection').onchange = function(e) {
        var font = this.options[this.selectedIndex].value,
            name = this.options[this.selectedIndex].textContent;
        if (font === 'default') {
            document.getElementById('sink').style.fontFamily = 'inherit';
        } else {
            document.getElementById('sink').style.fontFamily = name;
            replacestyle('https://fonts.googleapis.com/css?family=' + font);
        }
    };
}

jsonp("https://www.googleapis.com/webfonts/v1/webfonts?key=AIzaSyDBzzPRqWl2eU_pBMDr_8mo1TbJgDkgst4&sort=trending&callback=loadFonts");
<div id="container"></div>
<div id="sink">
<h1>HTML Ipsum Presents</h1>
           
<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>

<h2>Header Level 2</h2>
           
<ol>
   <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
   <li>Aliquam tincidunt mauris eu risus.</li>
</ol>

<blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote>

<h3>Header Level 3</h3>

<ul>
   <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
   <li>Aliquam tincidunt mauris eu risus.</li>
</ul>

<pre><code>
#header h1 a { 
    display: block; 
    width: 300px; 
    height: 80px; 
}
</code></pre>
</div>

我需要的是帮助在上面的代码中更改字体文件的来源,从谷歌字体指向一个自托管的字体文件夹,如果可能的话,我想将所选字体的 ID 或名称存储在 localStorage 中上述代码将能够跨会话加载它的方式。

标签: javascripthtmlcss

解决方案


更新 2021/7/27 20:00

您尝试修改的代码非常复杂。如果您有一个自托管字体文件夹,只需使用导入字体@font-face并创建一个简单的 HTML selection。

selection = document.querySelector('select#font')
selection.addEventListener('change', style)

function style()
{ document.body.style.fontFamily = selection.value }
<select name="font" id="font">
    <option value="Arial">Arial</option>
    <option value="Calibri">Calibri</option>
    <option value="Consolas">Consolas</option>
    <option value="Segoe UI">Segoe UI</option>
</select>

<h1>My First Heading</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pellentesque elit ullamcorper dignissim cras tincidunt. Interdum consectetur libero id faucibus. Libero nunc consequat interdum varius sit amet mattis vulputate.</p>
Interactive Code

您甚至不需要保存任何值,因为它已附加到body

您将需要保存一个值。选择的字体可以简单地保存到localStorage

localStorage.font = selection

并加载。

document.querySelector(`option[value=${localStorage.getItem(font)}]`).click()

更多信息请参见使用 Web 存储 API


推荐阅读