Skip to content

1210 今日总结

今日工作

  • 开发一个 类似 企业微信的 图片查看器,需要支持以下功能:
    • 弹框拖拽移动位置;
    • 弹框放大缩小
    • 弹框内图片移动位置
    • 弹框内图片放大缩小旋转
    • 底部预览列表展示
    • 左右图片切换

不写不知道,写了才知道自己的很多 js 问题不足:

1-滥用事件没有及时清除,新旧事件互相干扰:

js
// window.getEventListeners(dom) 使用这个 API 查看这个 dom 上有多少个事件

const img = document.querySelector('#img')
window.getEventListeners(img)

// resolve

useEffect(() => {
  // register
  const evFn = () => {}
  dom.addEventListerer('event', evFn)
  return () => {
    // remove
    dom.removeEventListerer('event', evFn)
  }
}, [])

2-使用正则匹配 transform: translate(x, y) scale(1.2) rotate(90deg) ,风险大;

场景:取出里面的属性数值,第一想法:使用正则,于是就有了以下:

js
// 正则-放大缩小的数值 scale(1.2)
const scalePattern = /scale\(([1-9]|[0-9]*(\.[0-9]{1,2})?)\)/;
// 正则-旋转角度的正则 rotate(90deg)
const rotatePattern = /rotate\((\-?\d+)deg\)/;
// 正则-图片偏移x, y 的正则 translate(x, y)
const offsetPatt = /translate\(((\-|\+)?\d+(\.\d+)?)px\, ((\-|\+)?\d+(\.\d+)?)px\)/;

暂且不说这些正则是否写错,但是不擅长写正则的我,这种处理方式确实风险很大;

随后,发现了新的思路:getComputedStyle 以及 matrix 矩阵

很明显,下面这种处理方式要好得多:

js
  //  matrix(scaleX, skew, rotate, scaleY, translateX, translateY)
  // 'matrix(  1,      0,    999,    1,      0,           0      )'  ======> [99, 100, 999, 1, 0, 0]
  let arr = window
    .getComputedStyle(dom)
    .transform.replace('matrix(', '')
    .replace(')', '')
    .split(',')
    .map(Number);
  const [scale, _, rotate, _1, translateX, translateY] = arr;

3-被 transform 属性搞懵了;

对照 AntD 的 Image 组件,写到一半踩坑:

我的实现:

html
<div class="img-wrapper">
  <img src="xxx" style="transform: translate(x, y) scale(1.2) rotate(90deg)">
</div>

错误的地方,在于我把 transform: translate(x, y) scale(1.2) rotate(90deg) 都作用在 img 标签上了,

问题就来了:

  • 当 图片旋转后,进行拖拽,方向错误;
  • 当图片放大后,拖拽图片,鼠标拖动距离和图片移动距离不一致

搞的晕头转向的;

参考 AntD 组件的 Image ,它是这么做的:

html
<div class="img-wrapper" style="transform: translate(x, y)">
  <img src="xxx" style="transform: scale(1.2) rotate(90deg)">
</div>

使用 图层概念

  • 图片图层只负责 缩放和旋转;
  • 外层的 wrapper 负责 拖拽移动,这样就避开了 img 里面的各种问题;

相关资料:

4- js 数字的精度问题

js
// 控制台输入
2.2 * 100

// 期待
// 220

// 结果
220.00000000000003

我的目的是最后只要 2 位小数,那么就应该在最后所有数学计算完成后再 toFixed(2)

今日心情

所见所想,有感而发

忙碌中...

感受到做技术攻关,克服了问题后的成就感;但是如果一直没有头绪的话,也很难受;

今日算法

今日学习:

今日复习:

手撕代码

防抖节流等各种手写,http和网络,浏览器原理,性能优化,Webpack

  • query 参数解析成对象

最简单:

js
// input
// https://www.baidu.com/s?name=tom&age=12

const url1 = 'https://www.baidu.com/s?name=tom&age=12'

const transformQuery = (url) => {
  const _url = new URL(url)
  return Object.fromEntries(new URLSearchParams(_url.search))
}

transformQuery(url1)
// { name: 'tom', age: '12' }

其他方法:

js
const url1 = 'https://www.baidu.com/s?name=tom&age=12'

const transformQuery = (url) => {
  const search = url.split("?")[1]
  let res = {}
  search.split("&").forEach(item => {
      const [key, name] = item.split("=")
      res[key] = name
  })

  // or
  // return search.split("&").reduce((pre, cur) => (pre[cur.split('=')[0]] = cur.split('=')[1], pre), {})
  return res
}

transformQuery(url1)

好文推荐

有感好文

代码贡献思路:

其实,对于 React 生态链,Vuejs 生态链,各自都有 hook,以及各种 工具链,但是很多工具函数本质都是 js 函数,实际上,互相 转译一下,就可以为 对应对生态链做 建设了。

好比 Java 有微服务,那么新出来的 Go 语言,是不是可以按照 Java 微服务的方式也写一套对应的 Go 微服务,与之特点结合做一些特性改造。

项目/博客推荐

值得学习的项目/作者

来源:https://github.com/SunshowerC/blog/issues/13

Released under the MIT License.