css3的attr函數(shù)使用,加載unicode圖標(biāo)

阿里矢量圖標(biāo)在項(xiàng)目中都用使用,通常一般我們引入css使用iconfont,或者我們使用svg加載圖標(biāo),亦或我們可以使用Unicode,除了第一種與第二種,今天分享第三種方式unicode加載圖標(biāo),希望看完在項(xiàng)目中能有所思考和幫助。

正文開始...

css加載圖標(biāo)
這是我們項(xiàng)目中最常用的一種方式

我在自己的iconfont[1]倉(cāng)庫(kù)中添加了幾個(gè)圖標(biāo)


打開前陣子我開源的一個(gè)移動(dòng)端項(xiàng)目topfreeApplication[2]

我們?cè)赾ommon.less中引入阿里矢量圖標(biāo)的這個(gè)css

/*src/assets/css/common.less*/
@import url('./normalize.less');
@import url('//at.alicdn.com/t/c/font_3470263_sw1krly77xh.css');
我在src/pages/home/component/Search.vue引入一個(gè)圖標(biāo)


所以加入了一行代碼,就將刪除圖標(biāo)就加入我們的頁(yè)面中了


svg圖標(biāo)
在這之前,我們都是用class方式加載,現(xiàn)在我們看下svg方式加載圖標(biāo)

在src/pages/home/component/Search.vue組件中也看到我使用一個(gè)svg-icon的二次組件加載圖標(biāo)的

我把svg-icon注冊(cè)成一個(gè)全局組件

<!--src/components/svg-icon/view/Index.vue-->
<script lang="tsx">
// 必須引入iconfont.js
import '@/assets/font/iconfont';
import { defineComponent, PropType, useAttrs } from 'vue';

export default defineComponent({
  name: 'SvgIcon',
  props: {
    name: {
      type: String as PropType<string>,
      default: '',
      required: true,
    },
    iconClass: {
      type: String as PropType<string>,
      default: '',
      required: false,
    },
  },
  render() {
    const { name, iconClass } = this;
    return (
      <svg class={`icon ${iconClass}`} aria-hidden="true" {...useAttrs()}>
        <use xlinkHref={`#icon-${name}`}></use>
      </svg>
    );
  },
});
</script>
<style lang="less" scoped>
.icon {
  fill: currentColor;
  overflow: hidden;
}
</style>
src/components/index.ts

import SvgIcon from './svg-icon';
import DataEmpty from './data-empty';

const customComponents = {
  SvgIcon,
  CDataEmpty: DataEmpty,
};

export const installComponent = (app) => {
  // 自定義注冊(cè)全局組件
  Object.keys(customComponents).forEach((key: string) => {
    app.component(key, customComponents[key]);
  });
};

注意我們必須引入iconfont.js具體可以參考使用web文檔[3]






uniCode 加載圖標(biāo)
我們注意到我們css加載圖標(biāo)實(shí)際上圖標(biāo)的一個(gè)偽類元素加載的一個(gè)unicode


加載圖標(biāo)實(shí)際上是引用了一個(gè)uncode,所以我們可以借雞生蛋

<template>
  <div class="search-bar">
    <div class="inner">
      <svg-icon name="sousuo" width="20" height="20" class="search-icon" />
      <input
        type="text"
        v-model="searchVal"
        @input="handleVal"
        class="input-search"
        placeholder="Search..."
      />
      <svg-icon
        name="guanbi"
        width="20"
        height="20"
        class="close-icon"
        @click="handleClear"
        v-if="searchVal"
      />
      <!-- <i class="iconfont icon-shanchu"></i> -->
      <i class="iconfont maic-del" unicode="&#xe718;"></i>
    </div>
  </div>
</template>
我們注意到我們?cè)趇標(biāo)簽上將icon-shanchu替換成了自己自定義的一個(gè)class,但同時(shí)也多了一個(gè)自定義屬性u(píng)nicode="&#xe718;",這是一個(gè)很有用的屬性,通常我們需要?jiǎng)討B(tài)的更換圖標(biāo)時(shí),我們就可以把這個(gè)unicode寫在標(biāo)簽上,那怎么才能顯示呢?

css有一個(gè)超強(qiáng)的函數(shù)特性attr,在css里面我們可以動(dòng)態(tài)的取到unicode的值

我們看下css代碼,注意unicode就是你標(biāo)簽上的那個(gè)屬性

 .maic-del {
  &::before {
    content: attr(unicode);
  }
 }
注意到?jīng)]有,利用attr這個(gè)特性就可以成功的加載到unicode了(不過注意,因?yàn)槲疫@個(gè)是vue3項(xiàng)目,在vue2中,我們必須v-html渲染這整個(gè)標(biāo)簽,不然圖標(biāo)始終顯示不出來)


所以你會(huì)發(fā)現(xiàn)在css中你用attr這個(gè)屬性就可以動(dòng)態(tài)的加載標(biāo)簽上的unicode了

css的Attr
在以上我們的圖標(biāo)用unicode就可以加載圖標(biāo),同時(shí)我們也知道利用css中的attr函數(shù)成功解決了圖標(biāo)加載問題

我們看看attr這個(gè)屬性可以在我們項(xiàng)目中怎么用,在哪些場(chǎng)景可以用?

我們嘗試寫一個(gè)計(jì)數(shù)器

  <div id="app">
    <button id="startBtn">開始計(jì)數(shù)</button>
    <div class="content" data-content="10"></div>
</div>
對(duì)應(yīng)的css

  * {
    padding: 0;
    margin: 0;
  }
  :root {
    --color: red;
    --width: 200px;
    --height: 200px;
  }
  #app {
    width: var(--width);
    height: var(--height);
    margin: 0 auto;
    border: 1px solid var(--color);
  }
  #app button {
    margin: 5px 10px;
  }
  .content {
    height: calc(var(--width) / 2);
    border: 1px solid green;
    text-align: center;
    line-height: calc(var(--width) / 2);
    font-size: 50px;
  }
  .content::before {
    content: attr(data-content);
    display: inline-block;
  }
我們使用了css3的函數(shù)var,以及calc,還有attr,這些都是css3的函數(shù),注意var中的變量必須在:root{}中用--xxx申明成全局,即可使用

看下布局后的基本頁(yè)面


我們?cè)倏聪聦?duì)應(yīng)的js
// requestAnimationFrame 模擬setInterval
 function customizeSetInterval(callback, interval) {
    let timer = null;
    let startTime = Date.now();
    let loop = () => {
      let endTime = Date.now();
      if (endTime - startTime >= interval) {
        startTime = endTime = Date.now();
        callback(timer);
      }
      timer = window.requestAnimationFrame(loop);
    };
    loop();
    return timer;
 }
  const startBtn = document.getElementById("startBtn");
  const contentDom = document.querySelector(".content");
  let initData = contentDom.dataset.content * 1;
  startBtn.onclick = function () {
    setCount();
  };
  // 計(jì)數(shù)操作
  function setCount(interval = 1000) {
    const timer = customizeSetInterval(() => {
    if (initData >= 0) {
        startBtn.innerText = "正在計(jì)數(shù)...";
        contentDom.setAttribute("data-content", initData--);
      }
       if (initData === -1) {
          startBtn.innerText = "重新計(jì)數(shù)";
        }
    }, interval);
    if (initData === -1) {
      initData = 10;
      window.cancelAnimationFrame(timer);
    }
  }
我們通過操作.content的data-content,因此可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的倒計(jì)時(shí)效果。

因此我們就用css中attr結(jié)合js實(shí)現(xiàn)了一個(gè)計(jì)數(shù)器功能,關(guān)于cssattr還有更多待挖掘的功能,在動(dòng)態(tài)改變圖標(biāo)等,attr是一種不錯(cuò)的選擇方案

總結(jié)
加載阿里矢量圖標(biāo)除了使用class與svg,我們也可以使用attr加載使用unicode

css3函數(shù)var,calc,attr的使用

使用css的attr特性簡(jiǎn)單實(shí)現(xiàn)計(jì)數(shù)器的效果

本文示例code example[4]

參考資料
[1]
iconfont: https://www.iconfont.cn/

[2]
topfreeApplication: https://github.com/maicFir/topfreeApplication

[3]
web文檔: https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.d8cf4382a&helptype=code

[4]
code example: https://github.com/maicFir/lessonNote/tree/master/html/07-attr




作者:Maic


歡迎關(guān)注微信公眾號(hào) :web技術(shù)學(xué)苑