我厂既然号称“机器编程”,DSL 便属于基础配置。于是,各个产品几乎都需要用到 CodeMirror,用于在线写代码。大家的屏幕分辨率不同,对编辑器的大小要求也不同,最简单的办法就是让大家自己调整,并且将尺寸保存在本地。
以前的做法会复杂一些:
- 拿一个元素作为 handle 放在角落里
- mousedown 时开始侦听 mousemove,动态调整文本框大小
- mouseup 时保存尺寸
如今大家应该都有注意到,<textarea>
右下角多了一个缩放用的 handle。这个功能自然不是 <textarea>
独享,而是受 CSS 样式 resize
控制,任何块级元素都适用。MDN 文档在此,建议大家先好好看一遍。
基于一般的网格化设计,包括响应式的需求,编辑器的宽度是固定的,用户控制的只有高度,所以我们只需要设置 resize: vertical
,让它接受垂直方面的缩放就可以了。
接下来该侦听缩放事件。可惜,resize
事件只有 window
可以触发(MDN 文档),所以直接在元素上侦听是不可能的了。好在我们有 MutationObserver,而 Resize Observer 也刚刚从草案变成现实,所以曲线一下就能满足这个需求。
onEditorResize([{target}]) {
const height = target.clientHeight;
if (height < 160) {
return;
}
localStorage.setItem(EDITOR_HEIGHT, height);
},
mounted() {
const onResize = debounce(this.onEditorResize, 1000);
const observer = this.observer = new MutationObserver(onResize);
observer.observe(element, {
attributes: true,
});
},
beforeDestroy() {
if (this.observer) {
this.observer.disconnect();
this.observer = null;
}
}
这里有几个 tips:
- 我用 Vue,所以用到一些生命周期的钩子
- 缩放动作会触发多次事件,所以最好用
debounce
降低执行频率 - 编辑器需要设置一个最小高度,不然可能不小心存一个
0px
,用户就看不到编辑器了 - 关于参数及含义,大家好好看文档吧。
欢迎吐槽,共同进步