SVG 图标引用问题

327 阅读1分钟

我正在参加「掘金·启航计划」

图标引用的问题

问题:当网络不佳的时候,图标会一个一个的出来。

如何把很多 svg 合并到一起

  1. iconfont 里查找 icon (问题 80% 部分图标上传就会错乱,要求比较严格)
  2. 把最外面一层的 svg 标签变成 symbol 标签

解决方案

情况一: 当只有几个 svg 标签

  • 把 svg 里的 <g></g> 全部拷贝一份出去(这里放到 buttons.svg 里)
  • <g></g> 标签换成 <symbol></symbol> , symbol 默认是不显示的。
// 设计师给的 svg 图标
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
  <g id="iPhone-8" transform="translate(-60.000000, -502.000000)" fill="#FD1BB8">
    <g id="喜欢" transform="translate(60.000000, 502.000000)">
      <path></path>
    </g>
  </g>
</g>

// 换成 symbol
<symbol id="icon-like" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
  <g id="iPhone-8" transform="translate(-60.000000, -502.000000)" fill="#FD1BB8">
    <g id="喜欢" transform="translate(60.000000, 502.000000)">
      <path></path>
    </g>
  </g>
</symbol>
// 放入到 buttons.svg 里 换成 symbol 标签,然后放入需要引入到 html 中
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
    <title>下载</title>
    <desc>Created with Sketch.</desc>
  <!-- id 可以自己命名/修改 -->
    <symbol id="icon-like" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
        <g id="iPhone-8" transform="translate(-60.000000, -502.000000)" fill="#FD1BB8">
            <g id="喜欢" transform="translate(60.000000, 502.000000)">
                <path ></path>
            </g>
        </g>
    </symbol>
</svg>
<div class="buttons">
  <!-- class 名自己可以取, xlink:href 需要和 symbol id 名 一致方可引用-->
  <svg class="btn-like"><use xlink:href="#icon-like"/></svg>
</div>

情况二:当遇到 svg 标签很多时

<?xml version="1.0" encoding="UTF-8"?>
<svg width="120px" height="120px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
    <title>上一首</title>
    <desc>Created with Sketch.</desc>
    <defs>
        <radialGradient cx="50%" cy="50%" fx="50%" fy="50%" r="50%" gradientTransform="translate(0.500000,0.500000),scale(1.000000,0.994186),translate(-0.500000,-0.500000)" id="radialGradient-1">
            <stop stop-color="#AC2D73" offset="0%"></stop>
            <stop stop-color="#120A82" offset="92%"></stop>
            <stop stop-color="#07006B" offset="100%"></stop>
        </radialGradient>
        <linearGradient x1="90.5072268%" y1="20.6957496%" x2="9.4941375%" y2="79.3043243%" id="linearGradient-2">
            <stop stop-color="#3B2EE8" stop-opacity="0.2" offset="0%"></stop>
            <stop stop-color="#FC429F" offset="25%"></stop>
            <stop stop-color="#B639E5" offset="87%"></stop>
            <stop stop-color="#FCFCFC" offset="100%"></stop>
        </linearGradient>
        <linearGradient x1="126.40209%" y1="13.5040932%" x2="-24.1592819%" y2="87.2715353%" id="linearGradient-3">
            <stop stop-color="#FC429F" offset="0%"></stop>
            <stop stop-color="#3B2EE8" offset="100%"></stop>
        </linearGradient>
        <linearGradient x1="67.8867993%" y1="30.9688504%" x2="75.4688625%" y2="21.1618118%" id="linearGradient-4">
            <stop stop-color="#FC57A9" offset="0%"></stop>
            <stop stop-color="#FCFCFC" offset="100%"></stop>
        </linearGradient>
        <linearGradient x1="61.4131653%" y1="33.8941487%" x2="39.4202448%" y2="71.4869303%" id="linearGradient-5">
            <stop stop-color="#B639E5" offset="0%"></stop>
            <stop stop-color="#3B2EE8" offset="100%"></stop>
        </linearGradient>
        <linearGradient x1="92.2146132%" y1="-4.63859816%" x2="10.4535745%" y2="110.070945%" id="linearGradient-6">
            <stop stop-color="#FC429F" offset="0%"></stop>
            <stop stop-color="#B639E5" offset="100%"></stop>
        </linearGradient>
    </defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="iPhone-8" transform="translate(-177.000000, -29.000000)">
            <g id="上一首" transform="translate(177.000000, 29.000000)">
                <g id="图-资源-12">
                    <ellipse id="Oval" fill="url(#radialGradient-1)" cx="60" cy="60.3278689" rx="56.0655738" ry="56.3934426"></ellipse>
                    <path d="M59.9548308,5.61469731 C86.7262364,5.59034291 109.53495,25.1646104 113.727249,51.7617846 C117.919548,78.3589588 102.24883,104.07023 76.7829298,112.377093 C51.3170297,120.683956 23.6283668,109.116322 11.5058441,85.1059517 C-0.616678668,61.0955812 6.4316347,31.7820844 28.1225135,15.9982575 C37.381525,9.2515634 48.5217809,5.61766153 59.9548308,5.61469731 Z M59.9548308,3.93450958 C33.9678996,3.96156583 11.4045662,21.9459534 5.43790156,47.387911 C-0.528763057,72.8298686 11.6648878,99.0619808 34.8998782,110.769246 C42.7110885,114.676325 51.3147233,116.713418 60.0383473,116.721311 C81.0928073,116.708669 100.365002,104.83052 109.936925,85.9670171 C119.508848,67.1035138 117.766372,44.4356389 105.425394,27.2765176 C94.8863331,12.5904686 77.9653263,3.9033857 59.9590067,3.93450958 L59.9548308,3.93450958 Z" id="Shape" fill="url(#linearGradient-2)" fill-rule="nonzero"></path>
                    <path d="M3.10837279,78.6885246 C-5.35495222,53.4533715 3.8779541,25.6687872 25.7703616,10.4918033 L28.852459,14.9558468 C8.92145404,28.7385915 0.519285038,54.0210331 8.24380779,76.9680513 L3.10837279,78.6885246 Z" id="Path" fill="url(#linearGradient-3)"></path>
                    <path d="M114.245163,65.6499501 C116.372688,46.0329572 107.677121,26.8058523 91.5234854,15.4091655 C75.3698494,4.01247878 54.2926478,2.23434907 36.4483634,10.7628794 L34.0983607,5.8762456 C53.7206607,-3.5030912 76.898549,-1.5488063 94.6627212,10.9828374 C112.426893,23.5144812 121.990192,44.6572978 119.651842,66.2295082 L114.245163,65.6499501 Z" id="Path" fill="url(#linearGradient-4)"></path>
                    <path d="M54.6247073,120 C35.5244375,118.320115 18.3772721,107.417802 8.52459016,90.6891545 L13.1637002,87.8688525 C22.1211082,103.081395 37.7137233,112.995026 55.0819672,114.520073 L54.6247073,120 Z" id="Path" fill="url(#linearGradient-5)"></path>
                    <path d="M64.6784245,119.344262 L64.2622951,113.931055 C86.6626643,112.2425 105.714136,96.9321406 112.196238,75.4098361 L117.377049,76.9630103 C110.258865,100.635232 89.3126319,117.480598 64.6784245,119.344262 Z" id="Path" fill="url(#linearGradient-6)"></path>
                </g>
                <g id="Group" transform="translate(62.295082, 61.639344) scale(-1, 1) translate(-62.295082, -61.639344) translate(40.655738, 40.655738)" fill="#FFFFFF">
                    <path d="M30.013345,18.4824896 C31.9627648,19.8670855 31.9627648,22.0908305 30.013345,23.4754264 L3.51281591,41.3283223 C1.56339608,42.7129182 -3.77064001e-08,41.7688755 0,39.2514284 L0,2.70648765 C0,0.189040535 1.5826973,-0.734023408 3.51281591,0.629593776 L30.013345,18.4824896 Z" id="Path"></path>
                    <rect id="Rectangle" fill-rule="nonzero" x="36.7213115" y="0" width="6.55737705" height="41.9672131" rx="3.27868852"></rect>
                </g>
            </g>
        </g>
    </g>
</svg>
<!-- 把 svg 改成 symbol 然后再用 svg 把所有的都包起来 -->
<!-- 设置如下的样式 -->
<?xml version="1.0" encoding="UTF-8"?>
<svg style="position:absolute; width: 0;heiht:0; overfllow: hidden" width="120px" height="120px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="icon-pre" width="120px" height="120px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
   <!--...--> 
</symbol>
</svg>
  
  <!-- html如何引用:通过 id -->
   <svg class="btn-download"><use xlink:href="#icon-pre"/></svg>
   <svg class="btn-download"><use xlink:href="#icon-next"/></svg>

使用 JS 引用

随着 svg 的变多,单纯的放到 html 中,会让其变得臃肿,故使用 JS 来引入 svg

icons.js

let  svgPlaceholder = document.createElement('div')
svgPlaceholder.style.position="absolute"
svgPlaceholder.style.width = 0
svgPlaceholder.style.height = 0
svgPlaceholder.style.overflow = "hidden"
// svgPlaceholder.style.display = "none"
document.body.appendChild(svgPlaceholder)
svgPlaceholder.innerHTML = `
<?xml version="1.0" encoding="UTF-8"?>
<svg style="display:none"  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
    <title>下载</title>
    <desc>Created with Sketch.</desc>
    <symbol id="icon-download" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
       ...
    </symbol>
    <symbol id="icon-share" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
        ...
    </symbol>
    <symbol id="icon-like" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
       ...
    </symbol>
    <symbol id="icon-more" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
       ...
    </symbol>
    <symbol id="icon-comment" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.8">
        ...
    </symbol>
</svg>




<?xml version="1.0" encoding="UTF-8"?>
<svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol id="icon-pre" width="28px" height="28px" viewBox="0 0 120 120">
    ...
    </symbol>
    <symbol id="icon-next" width="24px" height="24px" viewBox="0 0 120 120">
       ...
    </symbol>
    <symbol id="icon-play" width="50px" height="50px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>

    <symbol id="icon-order" width="24px" height="24px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>
    <?xml version="1.0" encoding="UTF-8"?>
    <symbol id="icon-list" width="24px" height="24px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>
    <?xml version="1.0" encoding="UTF-8"?>
    <symbol id="icon-pause" width="50px" height="50px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>
    <?xml version="1.0" encoding="UTF-8"?>
    <symbol id="icon-single" width="24px" height="24px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>

    <?xml version="1.0" encoding="UTF-8"?>
    <symbol id="icon-circle" width="28px" height="28px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>

    <?xml version="1.0" encoding="UTF-8"?>
    <symbol id="icon-inorder" width="28px" height="28px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    ...
    </symbol>
</svg>

在 index.js 中引入

import './icons.js'

在 html 中引用

   <div class="actions">
      <svg class="btn-order" xmlns:xlink="http://www.w3.org/1999/xlink"  aria-hidden="true"><use xlink:href="#icon-circle"/></svg>
      <svg class="btn-pre" xmlns:xlink="http://www.w3.org/1999/xlink"  aria-hidden="true"><use xlink:href="#icon-pre"/></svg>
      <svg class="btn-play-pause pause" xmlns:xlink="http://www.w3.org/1999/xlink"  aria-hidden="true"><use xlink:href="#icon-play"/></svg>
      <svg class="btn-next" xmlns:xlink="http://www.w3.org/1999/xlink"  aria-hidden="true"><use xlink:href="#icon-next"/></svg>
      <svg class="btn-music-list" xmlns:xlink="http://www.w3.org/1999/xlink"  aria-hidden="true"><use xlink:href="#icon-list"/></svg>
    </div>