目录
article
textarea 控件添加 Markdown 编辑器常用的几个快捷键
textarea 控件添加 Markdown 编辑器常用的几个快捷键
在 textarea 控件上添加了几个简单的快捷键,以方便编辑博客内容。功能比较简陋,仅实现了最简单的功能。
所有操作均支持通过 Ctrl + z 快捷键撤消。
具体快捷键如下:
Ctrl + i:斜体,在选中范围前后插入*,再次点击快捷键删除*。Ctrl + b:粗体,在选中范围前后插入**,再次点击删除**。`:行内代码,在选中范围前后插入`字符,再次点击删除。Tab:缩进,插入四个空格,支持多行。Shift + Tab:取消缩进,整行取消缩进至多 4 个空格,支持多行。Alt + ↑&Alt + ↓:上移或下移。Ctrl + /:添加 HTML 备注标签<!-- -->。
$("#Content").on(
'keydown',
function (e) {
const start = this.selectionStart;
const end = this.selectionEnd;
if (e.shiftKey && !e.ctrlKey && !e.altKey && e.code == "Tab") {
// Shift + TAB
e.preventDefault();
let strBefore = this.value.slice(0, start);
let curLineStart = strBefore.includes('\n') ? strBefore.lastIndexOf('\n') : 0;
let strBetween = this.value.slice(curLineStart, end);
let newStr = strBetween.replace(/\n {1,4}/g, '\n');
if (strBetween == newStr) {
return false;
}
let newStart = start;
let newEnd = end - strBetween.length + newStr.length;
this.setSelectionRange(curLineStart, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
} else if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.code == "Tab") {
// TAB
e.preventDefault();
if (start === end) {
document.execCommand('insertText', false, " ");
} else {
let strBefore = this.value.slice(0, start);
let curLineStart = strBefore.includes('\n') ? strBefore.lastIndexOf('\n') + 1 : 0;
let strBetween = this.value.slice(curLineStart, end);
let newStr = " " + strBetween.replace(/\n/g, '\n ');
let lineBreakCount = strBetween.split('\n').length;
let newStart = start;
let newEnd = end + lineBreakCount * 4;
this.setSelectionRange(curLineStart, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
}
} else if (!e.shiftKey && e.ctrlKey && !e.altKey && e.keyCode === 73) {
// Ctrl + i
e.preventDefault();
if (start === end) {
document.execCommand('insertText', false, "**");
this.setSelectionRange(start + 1, start + 1);
}
else {
let strBetween = this.value.slice(start, end);
if (strBetween.length > 1 && strBetween.indexOf('*') == 0 && strBetween.lastIndexOf('*') == strBetween.length - 1) {
let newStr = strBetween.substr(1, strBetween.length - 2);
let newStart = start;
let newEnd = end - 2;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
} else {
let newStr = "*" + strBetween + "*";
let newStart = start;
let newEnd = end + 2;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
}
}
} else if (!e.shiftKey && e.ctrlKey && !e.altKey && e.keyCode === 66) {
// Ctrl + B
e.preventDefault();
if (start === end) {
document.execCommand('insertText', false, "****");
this.setSelectionRange(start + 2, start + 2);
} else {
let strBetween = this.value.slice(start, end);
if (strBetween.length > 1 && strBetween.indexOf('**') == 0 && strBetween.lastIndexOf('**') == strBetween.length - 2) {
let newStr = strBetween.substr(2, strBetween.length - 4);
let newStart = start;
let newEnd = end - 4;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
} else {
let newStr = "**" + strBetween + "**";
let newStart = start;
let newEnd = end + 4;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
}
}
} else if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode === 192) {
// '`'
e.preventDefault();
if (start === end) {
document.execCommand('insertText', false, "`");
this.setSelectionRange(start + 1, start + 1);
} else {
let strBetween = this.value.slice(start, end);
if (strBetween.length > 1 && strBetween.indexOf('`') == 0 && strBetween.lastIndexOf('`') == strBetween.length - 1) {
let newStr = strBetween.substr(1, strBetween.length - 2);
let newStart = start;
let newEnd = end - 2;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
} else {
let newStr = "`" + strBetween + "`";
let newStart = start;
let newEnd = end + 2;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
}
}
} else if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode === 219) {
// '['
e.preventDefault();
if (start === end) {
document.execCommand('insertText', false, "[]");
this.setSelectionRange(start + 1, start + 1);
} else {
let strBetween = this.value.slice(start, end);
let newStr = "[" + strBetween + "]";
let newStart = start;
let newEnd = end + 2;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
}
} else if (e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode === 57) {
// '('
e.preventDefault();
if (start === end) {
document.execCommand('insertText', false, "()");
this.setSelectionRange(start + 1, start + 1);
} else {
let strBetween = this.value.slice(start, end);
let newStr = "(" + strBetween + ")";
let newStart = start;
let newEnd = end + 2;
this.setSelectionRange(start, end);
document.execCommand("insertText", false, newStr);
this.setSelectionRange(newStart, newEnd);
}
} else if (!e.shiftKey && !e.ctrlKey && e.altKey && e.keyCode === 38) {
// ALT + ↑
e.preventDefault();
const isFirstLine = this.value.lastIndexOf('\n', start) === -1;
if (isFirstLine) {
return;
}
const curAreaStart = isFirstLine ? 0 : this.value.lastIndexOf('\n', start - 1) + 1;
const isLastLine = this.value.indexOf('\n', end) === -1;
const curAreaEnd = isLastLine ? this.value.length : this.value.indexOf('\n', end);
const isNewFirstLine = this.value.lastIndexOf('\n', curAreaStart - 2) === -1;
const newAreaStart = isNewFirstLine ? 0 : this.value.lastIndexOf('\n', curAreaStart - 2) + 1;
if (isNewFirstLine) {
let strBetween = this.value.slice(curAreaStart, curAreaEnd + 1);
if (isLastLine) {
strBetween += "\n";
}
this.setSelectionRange(isLastLine ? curAreaStart - 1 : curAreaStart, curAreaEnd + 1);
document.execCommand('insertText', false, "");
this.setSelectionRange(newAreaStart, newAreaStart);
document.execCommand('insertText', false, strBetween);
} else {
let strBetween = this.value.slice(curAreaStart - 1, curAreaEnd);
this.setSelectionRange(curAreaStart - 1, curAreaEnd);
document.execCommand('insertText', false, "");
this.setSelectionRange(newAreaStart - 1, newAreaStart - 1);
document.execCommand('insertText', false, strBetween);
}
this.setSelectionRange(newAreaStart + start - curAreaStart, newAreaStart - curAreaStart + end);
} else if (!e.shiftKey && !e.ctrlKey && e.altKey && e.keyCode === 40) {
// ALT + ↓
e.preventDefault();
const isFirstLine = this.value.lastIndexOf('\n', start) === -1;
const curAreaStart = isFirstLine ? 0 : this.value.lastIndexOf('\n', start - 1) + 1;
const isLastLine = this.value.indexOf('\n', end) === -1;
if (isLastLine) {
return;
}
const curAreaEnd = this.value.indexOf('\n', end);
const isNewLastLine = this.value.indexOf('\n', curAreaEnd + 1) === -1;
const newAreaStart = isNewLastLine ? this.value.length : this.value.indexOf('\n', curAreaEnd + 1) + 1;
if (isNewLastLine) {
let strBetween = this.value.slice(curAreaStart - 1, curAreaEnd);
this.setSelectionRange(newAreaStart, newAreaStart);
document.execCommand('insertText', false, strBetween);
this.setSelectionRange(curAreaStart - 1, curAreaEnd);
document.execCommand('insertText', false, "");
this.setSelectionRange(newAreaStart + start - curAreaEnd, newAreaStart - curAreaEnd + end);
} else {
let strBetween = this.value.slice(curAreaStart, curAreaEnd + 1);
this.setSelectionRange(newAreaStart, newAreaStart);
document.execCommand('insertText', false, strBetween);
this.setSelectionRange(curAreaStart, curAreaEnd + 1);
document.execCommand('insertText', false, "");
this.setSelectionRange(newAreaStart + start - curAreaEnd - 1, newAreaStart - curAreaEnd - 1 + end);
}
} else if (!e.shiftKey && e.ctrlKey && !e.altKey && e.keyCode === 191) {
// Ctrl + /
e.preventDefault();
let curAreaStart = start;
let curAreaEnd = end;
if (start === end) {
const isFirstLine = this.value.lastIndexOf('\n', start) === -1;
curAreaStart = isFirstLine ? 0 : this.value.lastIndexOf('\n', start - 1) + 1;
const isLastLine = this.value.indexOf('\n', end) === -1;
curAreaEnd = isLastLine ? this.value.length + 1 : this.value.indexOf('\n', end);
}
let strBetween = this.value.slice(curAreaStart, curAreaEnd);
console.log(strBetween);
if (strBetween.indexOf("<!--") === 0 && strBetween.lastIndexOf("-->") === strBetween.length - 3) {
this.setSelectionRange(curAreaStart, curAreaEnd);
document.execCommand('insertText', false, strBetween.substr(4, strBetween.length - 7));
this.setSelectionRange(curAreaStart, curAreaEnd - 7);
} else {
this.setSelectionRange(curAreaStart, curAreaEnd);
document.execCommand('insertText', false, "<!--" + strBetween + "-->");
this.setSelectionRange(curAreaStart, curAreaEnd + 7);
}
} else {
return true;
}
}
)