为了找一个close图标,最后手搓了一个图标管理页面
前戏
正如标题所诉,当时在开发一个小demo时,需要一个close图标(也就是一个叉叉)。然后纠结症就犯了:
- 手搓一个CSS图标?也就几行css代码的事儿,通过伪元素
::before
、::after
这样这样,然后这样,就行了; - 还是去阿里的字体图标库走一遭儿?就一个小demo好像也没啥必要;
- 或者去图标库找一个差不多的copy一个svg代码?去哪个图标网站好呢?
打住打住!有这纠结的时间,一个叉叉早就搓出来了。
思考
于是乎,一顿机械化的操作,一个正儿八经的close图标就完成了。我想这种代码作为一个老前端人估计都要写烂了吧。relative...absolute...content...top...transform...rotate...
虽然不难,但这种重复性的代码写起来实在恶心。以前写过无数遍,如果能直接copy就好了,可是,一下子又不知上哪去copy。
如果有一个集中管理的地方就好了,需要的时候直接拿来就用,没有的图标也能够快速放上去以便下次使用。好了,几个重点:
- 集中管理;
- 拿来就用;
- 快速更新;
集中管理,那就做一个属于自己的图标管理页面,绑定好域名,需要的时候“唰”的一下就找到了。
拿来就用,页面上需要展示所有的图标,以及每个图标对应的代码。
至于快速更新,从纯前端出发,肯定是丢一段图标的css代码上去就行了。实现嘛?好像有点难度……
渲染图标
先在脑子里画一个草图:
这种简单的页面,也不需要啥啥全家桶了,直接用原始前端三件套来搞吧。
先写一个html
架子,大概就这样吧:
1 |
|
然后用css
来简单调一下样式,就不贴代码了。
最后我们来复习一下原生DOM操作的API吧,还记得你多久没写原生DOM操作了吗?
我们首先要定义一个图标数组,里面放图标的类名icon-close
:
1 |
|
遍历数组,生成图标DOM,需要用到document.createElement
API:
1 |
|
他们说,对于频繁操作DOM的时候,要先创建一个DocumentFragment
,然后再一次性添加到文档中。还记得这个前端优化点吧?尽量减少DOM的操作。
再将DocumentFragment
添加到DOM文档中去:
1 |
|
交互
交互很简单,就是点击图标的时候,右侧边栏显示对应的图标信息和代码。
首先,肯定是绑定事件了。好,考点又来了:对于一个动态的列表,我们的监听事件应该放在哪里比较好?
老前端人都知道,肯定放外面的容器上了!
1 |
|
首先说一个小小的优化点:我们每次点击图标的时候,都需要将之前的选中状态清掉,最直接的方法可能是遍历,我这里用了一个变量lastActiveIcon
来记录上一次选中的图标,因为每次有且只有一个图标能被选中。
其实上面的事件委托的写法还存在一个问题,就是当我们点击的是.icon-item
的子元素时,e.target
并不是我们需要的DOM元素。一开始我想到了用.icon-item * { point-events: none; }
将所有的子元素的点击事件都禁止掉,但这样总感觉不够优雅。
后来,在AI的帮助下,发现了一个APIclosest
(好吧,我承认自己没有印象了),这玩意儿用在这个场景是最合适不过了。于是就改了一下上面的代码:
1 |
|
完美解决!
渲染图标代码
图标渲染比较简单,首先就是cloneNode
一个图标,然后createElement
一些必要的信息,最后appendChild
到对应的DOM中去。
接下来问题来了,我们怎么渲染图标的代码呢?
html
代码相对比较简单,直接通过innerHTML
就能拿到,重点是css
代码好像有点不好拿。
有点印象的getComputedStyle
API,可以获取到元素的样式,可是这玩意儿拿到的是全量的样式代码,我们需要的CSS代码肯定是希望与定义时写的保持一致。
运行时好像不太好拿,那能不能在编译阶段就获取呢?理论上肯定是可行的,但这种方案还是作为最后的保留手段吧!
再次拿出AI,发现了一个document.styleSheets
API。没用过,去caniuse
上查一下,嗯,可以用。
这玩意儿可以拿到DOM上所有的样式表,然后通过遍历可以找到我们需要的样式表。为了寻找方便,我们可以给link
设置一个data-name
属性,并将我们的CSS图标代码放在icon.css
的独立文件中。
1 |
|
1 |
|
很好,CSS代码拿到了,就是格式有点乱,我们再简单的格式化一下吧。也不要用啥格式化工具库了,就几行代码没啥必要。我们观察一下,基本上就是在{
、}
和;
后面换行缩进一下就大差不差了。
1 |
|
最后提一下,还记得一开始我们定义的图标数组cssIcons
吗?既然已经可以拿到图标的样式表了,不如这一步手动定义也省了吧,直接动态生成我们的图标数组:
1 |
|
这样,以后添加图标的时候,只需要在icon.css
文件中贴上我们的CSS图标代码就搞定了。
最后,去网上扒了一些前端大佬的CSS图标,贴几个上去,让页面看起来不那么单调。
尾声
页面很简单,但完美的实现了一开始的几个需求点。
看一下最后的效果吧:https://demo.codingmo.com/demos/cssIcon/
项目已开源:https://github.com/moohng/demo/tree/main/demos/cssIcon
有任何想法也欢迎大家PR,反正都是玩嘛!
最后,我想说,作为一个老前端搬砖人,在写烦了千篇一律的业务代码时,偶尔给自己找点伪需求。欸,还别说,比起写那些无脑的增删改查还更有意思呢!