我正在寻找一种解决方案,使我能够使用 tab/shift-tab 来更改文本区域中选定多行的缩进,就像这里的 markdown 编辑器一样。
到目前为止,我正在寻找 Chrome 解决方案。
我想知道同样的事情,下面是一个函数,它将缩进/取消缩进您选择的内容并保持您的选择完整。它使用 4 个空格,但您可以在“if(e.shiftKey)”位中更改它以仅使用 2 个空格或制表符
function supportTabIndentation(textarea) {
const offsetToLineAndOffset = (lines, offset) => {
let line = 0
while (offset > lines[line].length && line < lines.length - 1) {
offset = offset - lines[line].length - 1
line++
}
return {line, offset}
}
const LineAndOffsetToOffset = (lines, line, offset) => {
for (let i = 0; i < line; i++)
offset += lines[i].length + 1
return offset
}
textarea.addEventListener('keydown', e => {
if (e.key == 'Tab') {
e.preventDefault()
const lines = e.target.value.split('\n')
const selection = [offsetToLineAndOffset(lines, textarea.selectionStart),
offsetToLineAndOffset(lines, textarea.selectionEnd)]
for (var l = selection[0].line; l <= selection[1].line; l++) {
const originalLength = lines[l].length
if (e.shiftKey) {
lines[l] = lines[l].replace(/^ {0,4}/, '')
} else {
lines[l] = ' ' + lines[l]
}
// How much the line moved
const delta = lines[l].length - originalLength
// Update the user selection if it's on this line
selection.forEach((sel) => {
if (sel.line == l) {
sel.offset = Math.max(0, sel.offset + delta)
}
})
}
textarea.value = lines.join('\n')
textarea.selectionStart = LineAndOffsetToOffset(lines, selection[0].line, selection[0].offset)
textarea.selectionEnd = LineAndOffsetToOffset(lines, selection[1].line, selection[1].offset)
}
})
}
supportTabIndentation(document.getElementById('editor'))
body{padding:0;margin:0;overflow:hidden;}
#editor{
background:#333;
position:absolute;
left:0;
right:0;
height:100vh;
width:100vw;
border:none;
resize:none;
color:white;
}
<textarea id="editor">
Select
Lines
And
Tab
Or
Shift
Tab
</textarea>