网页中添加特殊字体解决方案

前言

今天总结一下网页中添加特殊字体的解决方案。一个字体一般情况下很大,少则1-2M,一般是4-6M,大的字体十几兆的都有。加载在网页中会导致速度变得很慢,因此,你在网页中很少看到有用特殊字体的原因。今天主要总结一下网页中运用特殊字体的一些解决方案。

方案一:(针对有针对性的展示,死的文字)

目前市面上有很多字体压缩的方案,但是都是提供了具体的字体库,也就是你网页中用的文字,都在字体库里面,不在里面则网页中就不会展示。

Fontmin :ecomfe.github.io/fontmin/#ba...

文蜘:font-spider.org/

这种方案有明显的缺点,只适合死的文字展示,不适合动态添加。

方案二:运用woff2网页字体

这个可以参考张鑫旭的一篇文章:www.zhangxinxu.com/wordpress/2...

看了张鑫旭的文章之后,我用www.fontsquirrel.com/tools/webfo... 将我的ttf转换为woff2和woff

但是坑爹的问题来了,转换后的字体体积变得异常的小,我原来6m的字体,转换后才十几kb。我在网页中引用了转换后的字体,发现对中文无效,转换后只剩下英文了。

方案三:这是个传说

传说可以将字体转为js,然后通过加载js的方案来加载字体,该方式线上已经停止维护,地址是:cufon.shoqolate.com/generate/

但是他的github中还保留源代码github.com/sorccu/cufo...

感兴趣的可以下载下来,运行一下试一试。【只是一个工具源码,运行起来,上传字体转换一下试试】

方案四:我的解决方案

上面的三种方案都不适合我,我要在类似一个编辑器的页面,不停的切换字体。字体是用户输入的,我不知道用户会输入什么,因此,上面的方案对我来说全部都不适合。

我的方案思路:

字体虽然比较大,但是我可以异步加载,就是初始化的时候不加载字体,等用户用到了再加载,加载时按需加载,不是全部加载,用到哪个字体,就加载哪个字体。然后先判断用户电脑里面安装了这个字体没有,安装了就用本机的,没有安装再用线上的。

下面上一下我的代码【vue版本】

html如下:

ini 复制代码
<select class="inlineblock" v-model="templateData.currentItem.fontFamily" :disabled="templateData.currentItem.suoding">
	  <option value="HYYiSongJ">汉仪意宋简</option>
          <option value="HYZhongHeiJ">汉仪中黑简</option>
          <option value="HYZhongDengXianJ">汉仪中等线简</option>
          <option value="HYXueJunTiJ">汉仪雪君体简</option>
          <option value="HYXinRenWenSongJ">汉仪新人文宋简</option>
</select>

然后监听字体的变化:

kotlin 复制代码
  watch: {
    'templateData.currentItem.fontFamily': {
      immediate: true,
      handler(val) {
        this.changeFont(val)
      }
    }
  }

修改字体的函数如下:

scss 复制代码
changeFont(font) {
  this.appendArray.push(font) //判断头部有没有插入样式的数组
  const styles = `@font-face {
          font-family:'${font}';
            src: local('${font}'),
                url('/static/fonts/${font}.ttf');
        }`

  this.addCssByStyle(styles)
},

判断数组中有没有重复元素的函数(用正则):

javascript 复制代码
repeatornot(array) {
  return /(\x0f[^\x0f]+)\x0f[\s\S]*\1/.test('\x0f' + array.join('\x0f\x0f') + '\x0f')
}

增加到头部样式中的函数:

javascript 复制代码
addCssByStyle(cssString) {
  // console.log(this.repeatornot(this.appendArray), this.appendArray)
  if (!this.repeatornot(this.appendArray)) { // 判断头部样式中有没有新增,假如头部中有了这个字体,就不添加了,没有就添加
    let doc = document
    let style = doc.createElement('style')
    style.setAttribute('type', 'text/css')

    if (style.styleSheet) { // IE
      style.styleSheet.cssText = cssString
    } else { // w3c
      let cssText = doc.createTextNode(cssString)
      style.appendChild(cssText)
    }

    let heads = doc.getElementsByTagName('head')
    if (heads.length) { heads[0].appendChild(style) } else { doc.documentElement.appendChild(style) }
  }
},

核心代码就在上面,另外附上判断用户电脑里面是否安装了某个字体的函数库:

javascript 复制代码
var isSupportFontFamily=function(f){if(typeof f!="string"){return false}var h="Arial";if(f.toLowerCase()==h.toLowerCase()){return true}var e="a";var d=100;var a=100,i=100;var c=document.createElement("canvas");var b=c.getContext("2d");c.width=a;c.height=i;b.textAlign="center";b.fillStyle="black";b.textBaseline="middle";var g=function(j){b.clearRect(0,0,a,i);b.font=d+"px "+j+", "+h;b.fillText(e,a/2,i/2);var k=b.getImageData(0,0,a,i).data;return[].slice.call(k).filter(function(l){return l!=0})};return g(h).join("")!==g(f).join("")};

语法:

scss 复制代码
isSupportFontFamily(fontFamily);

小结

以上就是我总结的实现网页中添加特殊字体的集中方案,假如你有更好的方案,欢迎留言给我!

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax