【翻译】如何实现一个纯CSS计时器
前言有时我们会在页面上使用计时器。通常我们会用js实现计时器功能,但某些时候更适合用css,比如某些邮件客户端不支持运行js。 4个属性 counter():一个css函数,返回一个代表计数器的当前值的字符串。它通常和伪元素搭配使用,但是理论上可以在支持值的任何地方使用。 1counter(计数器名称); @property:自定义css属性,兼容性不是特别好,值的类型可以是integer、number、color、url、percentage、transform-function等。 123456@property --property-name { syntax: "<color>"; // 值类型检测 inherits: false; // 是否允许继承 initial-value: #c0ffee; // 默认值...
实现自定义脚手架
为什么要自定义脚手架?首先,每次创建项目后都需要很多重复性操作,比如安装UI库、css预处理器。在业务层面,每次也要添加一些必备的功能,比如登录、404页面等。其次,可以锻炼自己的技术。 脚手架的功能脚手架创建项目的流程: 让用户选择模板; 根据用户输入填充模板; 下载模板文件到创建的新文件夹中; 从框架来看,创建项目的时候需要选择是vue框架还是react框架,以及是否需要添加 typescript。 从插件来看,需要安装UI库、CSS预处理器、路由、全局状态管理器。 从项目功能来看,还需要封装fetch请求、登录、未登录页面、404页面、部署配置文件。 再参考一下vite,所以我们可以先设置几个模板,然后把小功能填充到模板里面。 具体的逻辑1.判断远程是否有更新版本,如果有询问用户是否更新。 当前版本从package.json中获取。 远程版本用exec()获取: 1exec('npm show xx version', (error, stdout, stderr) =>...
给svg设置cursor不生效
前言项目中一般用 svg 做小图标或背景图,背景图不需要设置 cursor, 小图标会写成单个的 IconXx.vue 文件。前不久遇到一个需求,需要展示 svg,并且可点击,这就需要设置 cursor,但直接设置不会生效。 svg 插入页面的方法SVG 文件可通过以下标签嵌入 HTML 文档:<embed>、<object>、<iframe>。SVG的代码可以直接嵌入到HTML页面中,或您可以直接链接到SVG文件。 1234567891011<embed src="circle1.svg" type="image/svg+xml" /><object data="circle1.svg" type="image/svg+xml"></object><iframe src="circle1.svg"></iframe><svg...
git LFS解决大文件上传
前言git 限制上传文件大小在 100M 以内。在日常工作中,偶尔会遇到某次提交的文件总量过大或者某个文件过大,所以在此记录一下如何解决这个问题。 分批次提交如果是提交很多文件,但单文件都不大的时候,可以选择分批次提交。如果已经 commit 才发现文件总量过大,则需要撤销 commit 。以下是会用到的 git 命令。 123git reflog 查看所有操作的历史记录git reset HEAD^2 上上一个版本git reset @~ 撤销一次commit 如果仅撤销上一次,则直接用第3条命令。如果在尝试解决问题时进行了多次 commit,则可以通过第1条命令查询想要回退到的版本,然后通过第2条命令回退。 LFS首先,下载git LFS。然后,关联需要用 LFS 上传的文件,比如下面的命令。 1git lfs track 'xx.mp4' 最后,按照正常的提交流程进行提交。 以下是可能用到的命令 12345# 关联某类型文件git lfs track '*.mp4' # 查找大于 nM 的文件find ./ -size +100M
常见的hover菜单缝隙问题
前言经常遇到hover时显示二级菜单的需求,在这个需求中,需要注意的是鼠标经过缝隙的时候菜单会隐藏。使用transition可以在经过缝隙时仍显示菜单,但如果在缝隙停留时间超出动画时间则菜单仍会隐藏。 初级可以用transition来解决鼠标经过缝隙时二级菜单隐藏的问题。但transition只有零点几秒的动画时间,如果鼠标停留缝隙的时间超出动画时间则二级菜单仍会隐藏。jcode 进阶版可以给触发菜单的元素和二级菜单之间填充一个透明的元素,这个透明元素是二级菜单的伪元素。这样,无论鼠标停留在缝隙多久,二级菜单都不会隐藏。jcode 总结css博大精深!
为什么只这一个接口502呢?
前言前几天遇到了一个没见过的bug,在此记录一下。前几天,新写了一个页面,里面有get请求、json参数的post请求、form参数的post请求,然后把这个项目打包出来的dist放入node中。更新到线上以后,发现仅有json参数的post请求出现nginx 502报错,其他接口都正常。 解决问题的思路刚开始搜索了一下nginx 502,没发现什么有用信息。 首先是发现其他get接口都正常,点击按钮时这个post接口报错,当时就有点懵。然后检查了同一个项目另一个post接口,发现另一个post接口也正常。所以,推理得json类型参数的post请求有问题。 本地环境,这个json参数的请求没问题,测试环境是用dist+nginx部署的,这个请求也没问题。线上环境是dist+node部署,所以就定位到了http-proxy-middleware这个库。 在node+dist项目中,如果接口就是这个node的就不用代理了,但如果前端代码中请求了别的项目的接口,就需要用http-proxy-middleware添加代理配置。 搜索http-proxy-middleware...
一个看起来只有2个字长度却有8的字符串引起的bug
前言我们有一个需求,用户的昵称如果长度超过6就截取前6个字符并显示…。今天,测试突然提了一个bug,某个用户的昵称只显示了…,鼠标hover的时候又显示2个字的昵称。刚看到这个问题的时候我也是一头雾水。 找出原因在看到这个现象后,我发现其他昵称都显示正常,但实在摸不着头脑这到底是怎么回事。然后查看了一下其他2个字的昵称是没问题的,然后通过console.log发现这个昵称居然长度有8,走了截取的分支。然后通过google发现这里面应该包含了零宽字符。其实,第一时间就应该想到这个字符串不对劲的,但完全忘记了零宽字符的存在,走了不少弯路。 在查找的过程中发现,Array.from可以查看字符串的真实长度,除了emoji。 不过Array.from并不能解决我的问题。 使用正则匹配unicode码点过滤零宽字符在网上找了个方法来过滤掉这些看不见的字符,最常见的解决方案就是下面这行代码。 1str.replace(/[\u200b-\u200f\uFEFF\u202a-\u202e]/g,...
canvas之measureText测量文本
前言这篇文章讲的是关于canvas的一个方法:measureText,这个方法接受一个字符串参数,返回关于这个字符串的宽度和水平线到顶部或底部的距离等等。主要涉及的知识点有:获取文本宽度、文本在垂直方向的对齐方式、基线、行高。 获取字符串宽度1234567<canvas id="canvas" width="200" height="200"></canvas><script> const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); context.font = '16px Microsoft YaHei'; ...
第一次开发node接口-干货总结
技术栈:node + express + mongoosegit地址,可直接使用。 nodemon 热更新使用nodemon启动项目,可以在修改代码时不用重新启动。 12// 安装npm i nodemon 安装之后,修改启动命令, 123456// package.json{ "scripts": { "start": "nodemon index.js" }} 中间件body-parserbody-parser解析请求参数,使我们可以通过req.body.xx访问参数。 123// index.jsvar bodyParser = require('body-parser');app.use(bodyParser.json()); cookie-parsercookie-parser解析请求携带的cookie,使我们可以通过req.cookies访问cookie。 1const email =...
从0到1实现一个npm库
项目的目录结构首先创建一个空项目, 12npm create vue@lastestnpm i 然后把components从src中挪到根目录下,把src改名为examples,修改index.html中main.ts的路径。具体的项目结构如下所示: components examples node_modules public index.html package.json vite.config.ts 导出组件在components/index.ts中定义导出的组件。以下代码是导出单个组件, 123456789101112// components/index.tsimport { App } from 'vue';import MyButton from './Button';const MyButtonPlugin = { install: (app: App) => { app.component('MyButton', MyButton); ...