Skip to main content

5 posts tagged with "js"

View All Tags

js数组转对象reduce

· 2 min read

需求场景

最近在写一个小程序端类似于github calendar的功能。参考了一些源码发现都是svg形式或者react的,并且第一格都代表周日,不符合中国周一是第一天的习惯。小程序没法直接用,没办法只能自己造轮子了。写的过程中有一个需要将数组转为对象,然后新的对象再和另一个数组合并的功能。其中数组转对象,我就使用了最简单的for循环。然而后面却发现使用reduce方式也可以实现数组转对象,这是什么操作,花里胡哨啊。

Reduce实现的优点

for循环实际是命令式编程,reduce是函数式编程。函数式编程的一个优点就是看起来比较清晰,性能当然没那么好。不过这年头还是代码清晰易维护重要啊,性能等出现了再去优化也不迟。

const dataTmp = data.reduce((target, v) => {
let day = getDayOfYear(new Date(v.date))
target[day] = v;
return target;
}, {});
const dataTmp={};
for(let i=0;i<data.length;i++){
let day = getDayOfYear(new Date(data[i].date))
dataTmp[day]=data[i]
}

贴一下自己实现的github calendar,后续抽空继续优化。https://github.com/zenonux/calendar-graph

html2canvas截图白屏,图片偏移终极解决方案

· 2 min read

需求场景

需要实现活动页面,点击分享弹出海报图片,并长按保存

图片偏移原因一:滚动条相关

html2canvas 的参数中,有 2 个参数,x,y。是裁剪位置的 x,y 坐标。x 方向一般没有滚动条,问题不大,y 方向一般是有滚动条的,这个时候就要算上滚动条偏移的距离才可以。

图片偏移原因二:transform 属性

解决掉滚动条导致的偏移问题后,ios 下截图没有偏移问题了,但是安卓会出现。经过多次调试及搜索相关资料,终于发现是因为弹窗使用了 transform 属性。后来去掉 transform 使用 flex 解决了。

截图空白原因三:图片未加载完成就调用 html2canvas

这个问题也是显而易见的,图片还没加载好就截图,肯定会出现问题。

其他问题:图片跨域

需要使用 useCORS 属性,并且服务器开启 Access-Control-Allow-Origin : *,当然也可以使用代理方式

终极解决方案代码

const sharePosterImg = ref("");

// 等待海报中的图片加载完成
await loadImage(needLoadImg);
// vue等待页面渲染完成
nextTick(() => {
const sharePoster = document.getElementById("share-poster");
//计算图片宽高,偏移距离,滚动条偏移距离
html2canvas(sharePoster, {
//允许跨域
useCORS: true,
scale: 2,
width: sharePoster.offsetWidth,
height: sharePoster.offsetHeight,
x: sharePoster.getBoundingClientRect().left,
//需要加上滚动条偏移距离
y: window.pageYOffset + sharePoster.getBoundingClientRect().top,
}).then((canvas) => {
//赋值base64
sharePosterImg.value = canvas.toDataURL("image/png");
});
});

源码理解:手写EventBus

· One min read
class EventBus {
map = {}

on(type, handler) {
this.map[type] = (this.map[type] || []).concat(handler)
}

fire(type, data) {
this.map[type] && this.map[type].forEach(handler => handler(data))
}

off(type, handler) {
if(this.map[type]) {
if(!handler) {
delete this.map[type]
} else {
let index = this.map[type].indexOf(handler)
this.map[type].splice(index, 1)
}
}
}
}

const eventBus = new EventBus()

eventBus.on('click:btn', data => {
console.log(data)
})

eventBus.fire('click:btn', {a: 1, b: 2})
eventBus.off('click:btn')
eventBus.fire('click:btn', {a: 1, b: 2})

js常用正则表达式整理

· 2 min read

在线正则表达式工具

基于Web开发者助手FeHelper修改的在线正则表达式工具

常用字符

#匹配中文字符                  /[\u4e00-\u9fa5]/gm
#匹配双字节字符 /[^\x00-\xff]/igm
#匹配行尾行首空白 /(^\s*)|(\s*$)/
#只能输入数字 /^\d+$/
#只能输入n个数字 /^\d{n}$/
#至少输入n个以上的数字 /^\d{n,}$/
#只能输入m到n个数字 /^\d{m,n}$/
#只能由英文字母组成 /^[a-z]+$/i
#只能由大写英文字母组成 /^[A-Z]+$/
#只能由英文和数字组成 /^[a-z0-9]+$/i
#只能由英文、数字、下划线组成 /^\w+$/

常用表单

#匹配Email地址          /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/   
#匹配URL地址 /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i
#匹配手机号码 /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/
#匹配身份证号 /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/
#匹配邮编号 /^[1-9]\d{5}(?!\d)$/
#匹配日期(yyyy-MM-dd) /^[1-2][0-9][0-9][0-9]-[0-1]{0,1}[0-9]-[0-3]{0,1}[0-9]$/