这篇内容是在有道云旧笔记基础上重新整理的 JavaScript 与前端开发 笔记。原始记录偏碎片化,这里补充了使用场景、阅读顺序和落地时需要注意的边界,方便以后在项目里快速复用。

适用场景 ​

  • 前端业务中需要快速处理数据、DOM、浏览器能力或通用工具函数时参考。
  • 把散落在项目里的小技巧抽成可复用代码片段,减少重复实现。
  • 排查兼容性和边界输入问题前,先用本文示例确认核心思路。

核心要点 ​

  • 正文以代码或命令片段为主,阅读时建议先确认目标问题,再挑选对应片段验证。
  • 保留了 1 段可直接参考的代码或命令,主要涉及 javascript,复制前需要按当前项目路径、版本和变量名做调整。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
const maxLength = 5000 // 允许最大输入限制
const E = window.wangEditor
const {
BtnMenu,
DropListMenu,
PanelMenu,
DropList,
Panel,
Tooltip
} = E
const _editor = this
const menuTitle = {
codingMenuTitle: ['代码模式', '文本模式'],
switchoverMenuTitle: ['更多功能', '极简功能'],
}
const menuAll = [
'head',
'bold',
'fontSize',
'fontName',
'italic',
'underline',
'strikeThrough',
'indent',
'lineHeight',
'foreColor',
'backColor',
'link',
'list',
'todo',
'justify',
'quote',
'emoticon',
'image',
'video',
'table',
'code',
'splitLine',
'undo',
'redo'
]
const menuBrief = [
'head',
'bold',
'fontSize',
'fontName',
'code',
'high',
'coding',
'switchover'
]
class CodingMenu extends BtnMenu {
constructor(editor) {
// data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
const $elem = E.$(
`<div class="w-e-menu" data-title="${menuTitle.codingMenuTitle[0]}"><i class="iconfont icon-codelibrary"></i></div>`
)
super($elem, editor)
}
// 菜单点击事件
clickHandler() {
// 做任何你想做的事情
_editor.codingSource(this.editor, this.$elem)
this.tryChangeActive()
}
tryChangeActive() {
if (_editor.isHTML) {
this.active()
} else {
this.unActive()
}
}
}
class SwitchoverMenu extends BtnMenu {
constructor(editor) {
// data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
const $elem = E.$(
`<div class="w-e-menu" data-title="${menuTitle.switchoverMenuTitle[0]}"><i class="iconfont icon-caidan"></i></div>`
)
super($elem, editor)
}
// 菜单点击事件
clickHandler() {
_editor.switchoverSource(this.editor, this.$elem)
this.tryChangeActive()
}
tryChangeActive() {
if (_editor.isHTML) {
this.active()
} else {
this.unActive()
}
}
}
function codingSource(editor, elem) {
const {
title
} = elem.elems[0].dataset
if (title === menuTitle.codingMenuTitle[0]) {
$(elem.elems).attr('data-title', menuTitle.codingMenuTitle[1]).addClass('lan-w-active')
} else {
$(elem.elems).attr('data-title', menuTitle.codingMenuTitle[0]).removeClass('lan-w-active')
}
let html = editor
editor.isHTML = !editor.isHTML
let source = html.txt.html()
source = html.isHTML ?
source.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/ /g, "&nbsp;") :
editor.txt.text().replace(/&lt;/ig, "<").replace(/&gt;/ig, ">").replace(/&nbsp;/ig, " ")
html.txt.text(source)
}
function switchoverSource(editor, elem) {
const {
title
} = elem.elems[0].dataset
const {
menuList
} = editor.menus
if (title === menuTitle.switchoverMenuTitle[0]) {
menuList.forEach(i => i.$elem.hasClass('lan-w-hide') && i.$elem.removeClass('lan-w-hide'))
$(elem.elems).attr('data-title', menuTitle.switchoverMenuTitle[1]).addClass('lan-w-active')
$(elem.elems).children().removeClass('icon-caidan').addClass('icon-zuixiaohua')
} else {
$(elem.elems).attr('data-title', menuTitle.switchoverMenuTitle[0]).removeClass('lan-w-active')
$(elem.elems).children().removeClass('icon-zuixiaohua').addClass('icon-caidan')
menuList.forEach(i => !menuBrief.includes(i.key) && i.$elem.addClass('lan-w-hide'))
}
setArticleLeftHeight()
}
E.registerMenu('coding', CodingMenu)
E.registerMenu('switchover', SwitchoverMenu)
const wangEditorHight = 560
const editorLeft = new E('#article-left')
editorLeft.config.height = wangEditorHight
editorLeft.config.border = false
editorLeft.config.menus = menuAll
editorLeft.create()
// 自定义初始化菜单
function initializeMenu() {
document.getElementById('totality').innerText = maxLength
// document.querySelector('.result-box').style.cssText = `min-height: ${wangEditorHight}px`
// result-box
const {
menuList
} = editorLeft.menus
if (menuList && menuList.length) {
menuList.forEach(i => !menuBrief.includes(i.key) && i.$elem.addClass('lan-w-hide'))
// menuList.map((t, i) => i === .indexOf('switchover') && menuList.push(menuList.splice(i, 1)[0]))
}
setArticleLeftHeight()
}
function setArticleLeftHeight() {
const articleLeftHeight = document.getElementById('article-left').offsetHeight
// const headerHeight = document.querySelector('.score').offsetHeight + document.querySelector('.sentence.head').offsetHeight
const headerHeight = document.querySelector('.score').offsetHeight
console.log(headerHeight || 40)
document.getElementById('sentence').style.cssText = `height: ${articleLeftHeight - (headerHeight || 40)}px`
document.getElementById('article-right').style.cssText = `height: ${articleLeftHeight}px`
}
initializeMenu()
// 左编辑器 文本监听
editorLeft.config.onchange = function (newHtml) {
const htmlStings = getHtmlStings(newHtml)
const htmlLength = htmlStings.length
if (htmlLength) {
const wordCount = document.getElementById('word-count')
wordCount.innerText = htmlLength
if (htmlLength > maxLength) {
wordCount.innerHTML = `<span class="warning">${htmlLength - maxLength}</span>`
} else {
wordCount.innerText = htmlLength
}
}
}
// 点击按钮选中复制
const clipboard = new ClipboardJS('#copy-btn', {
// text: function(e) {
// const safeHtml = editorLeft.txt.html();
// if (!safeHtml) {
// toast({time: 2000, msg: '还没有生成任何内容哦'})
// return false;
// }
//    return safeHtml;
// }
target: function(trigger) {
return document.querySelector('.w-e-text')
}
});

实践检查清单 &#8203;

  • 把示例函数放进业务前,先补齐空值、异常输入、异步失败和浏览器兼容性测试。
  • 通用工具函数应尽量收敛到项目公共模块,避免多个页面复制出不同版本。
  • 涉及 UI 或浏览器行为时,至少在桌面端和移动端各验证一次关键路径。

复盘小结 &#8203;

这篇笔记更适合作为问题排查或方案落地前的速查材料。后续如果在真实项目中再次遇到同类问题,可以继续把具体版本、报错信息、最终取舍和验证结果补到对应小节里,让它从代码片段逐步沉淀成完整方案。