8

Vue 根据文字数量动态调整字体大小以适合容器

 3 years ago
source link: https://blog.skyju.cc/post/vue-auto-font/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Featured image of post Vue 根据文字数量动态调整字体大小以适合容器

技术

Vue 根据文字数量动态调整字体大小以适合容器

这是最近开发闪卡项目遇到的问题。不同卡片虽然宽高一样,但里面的内容即字数有所不同。对于文字数量小的卡片而言,需要字体大小为一个合适的值;而对于文字数量大的卡片则需要将字体调小,在不溢出容器的前提下尽可能大。

Jan 17, 2022   By  居正

这是最近开发闪卡项目遇到的问题。不同卡片虽然宽高一样,但里面的内容即字数有所不同。对于文字数量小的卡片而言,需要字体大小为一个合适的值;而对于文字数量大的卡片则需要将字体调小,在不溢出容器的前提下尽可能大。

模块代码片段:(gist地址:https://gist.github.com/juzeon/35c47d738e658fe837734d8b42538bf2

<template>
  <div :style="'height: '+containerHeight" ref="container" class="d-flex justify-center align-center"
       v-intersect="resizeFont">
    <div ref="text" v-html="textHtml" style="word-break: break-all;line-height: normal;">

    </div>
  </div>
</template>

<script>
export default {
  name: "AutoFont",
  props: ['containerHeight', 'defaultFontSize', 'textHtml'],
  mounted() {
    this.resizeFont()
  },
  updated() {
    this.resizeFont()
  },
  methods: {
    resizeFont() {
      let containerEl, textEl
      containerEl = this.$refs.container
      textEl = this.$refs.text

      textEl.style.fontSize = this.defaultFontSize + 'px'
      let fontSize = this.defaultFontSize
      for (let i = 0; i < 100; i++) {
        if (containerEl.clientHeight < textEl.clientHeight) {
          fontSize--
          textEl.style.fontSize = fontSize + 'px'
        } else {
          break
        }
      }
    },
  }
}
</script>

<style scoped>
img{
  max-height: 250px;
}
</style>

由于程序本身用到vuetify库,因此代码中d-flex justify-center align-center等类名均是来自于此。

模块以传入的字体大小为基准字体大小,并将传入的容器高度认为是外部容器高度。

在DOM已经渲染完毕的情况下,通过this.$refs获取DOM元素本身。

每次调整步长为fontSize-1,也可以设置的更小。

调整后对比字体元素和容器元素的clientHeight,若仍然溢出则继续调整。

为防止出现意外情况导致无限循环,设置最大调整次数为100次,这里也可以自行更改到一个合适值。

但遇到一个问题,vue组件挂载完毕并不意味着组件显示在用户界面上。例如当组件的displaynone时获取到的clientHeight为0,这时候调整会出现问题。因此设置了交叉观察者v-intersect(这是vuetify对浏览器原生交叉观察者的封装)事件,当组件显示/隐藏在用户界面上时均重新调整。

Licensed under CC BY-NC-SA 4.0


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK