将字符插入 contenteditable 元素时出现文本光标问题
Text cursor problem when inserting characters into a contenteditable element
有一个 contenteditable 的 pre 元素。我想通过 TAB 按钮添加制表符。所以,我添加了名为 putTab
的 js 方法。这种方法工作正常。但是有一个关于文本光标的问题。 正常输入时,视图不断向右移动。但是当按下tab键时,view在行尾后并没有继续向右滑动。然后比如我按下'A'键的时候突然向右滑动得到了预期的view
在JS方法中添加字符后,我找不到任何关于跟随文本光标的明确信息:
function putTab() {
var pre = document.getElementById("typearea");
var doc = pre.ownerDocument.defaultView;
var sel = doc.getSelection();
var range = sel.getRangeAt(0);
var tabNode = document.createTextNode(" ");
range.insertNode(tabNode);
range.setStartAfter(tabNode);
range.setEndAfter(tabNode);
sel.removeAllRanges();
sel.addRange(range);
}
document
.querySelector('button')
.addEventListener('click', putTab);
#typearea {
overflow-x: hidden;
margin: 8px;
max-height: auto;
white-space: pre;
display: block;
width: auto;
line-height: 1.5;
}
<button>Insert Tab</button>
<pre id="typearea" contenteditable>
Some predefined text.
</pre>
希望我把问题说清楚了,谢谢
由于 OP 提供了使可编辑内容至少水平滚动的样式,因此内容在向其附加额外字符时需要再次滚动到其父视图中。
因此,OP 可以使用 content-editable 容器的 scrollTo
方法。但话又说回来,OP 必须弄清楚何时(附加内容)和何时不(例如,在光标仍然完全对齐时预先添加或插入内容)来应用此方法。
但是使用容器的scrollBy
方法涵盖任何场景。
function putTab() {
var pre = document.getElementById("typearea");
var doc = pre.ownerDocument.defaultView;
var sel = doc.getSelection();
var range = sel.getRangeAt(0);
const scrollWidthBefore = pre.scrollWidth;
var tabNode = document.createTextNode(" ");
range.insertNode(tabNode);
range.setStartAfter(tabNode);
range.setEndAfter(tabNode);
sel.removeAllRanges();
sel.addRange(range);
pre.scrollBy(pre.scrollWidth - scrollWidthBefore, pre.scrollHeight);
// // perfect approach for appending content
// // but leads to out of view scrolling in
// // all other cases of perfectly visible
// // content like prepending content or
// // inserting it.
//
// pre.scrollTo(
// pre.scrollWidth - parseFloat(window.getComputedStyle(pre).getPropertyValue('width')),
// pre.scrollHeight,
// );
}
document
.querySelector('button')
.addEventListener('click', putTab);
#typearea {
overflow-x: hidden;
margin: 8px;
max-height: auto;
white-space: pre;
display: block;
width: auto;
line-height: 1.5;
}
<button>Insert Tab</button>
<pre id="typearea" contenteditable>Some predefined content.</pre>
有一个 contenteditable 的 pre 元素。我想通过 TAB 按钮添加制表符。所以,我添加了名为 putTab
的 js 方法。这种方法工作正常。但是有一个关于文本光标的问题。 正常输入时,视图不断向右移动。但是当按下tab键时,view在行尾后并没有继续向右滑动。然后比如我按下'A'键的时候突然向右滑动得到了预期的view
在JS方法中添加字符后,我找不到任何关于跟随文本光标的明确信息:
function putTab() {
var pre = document.getElementById("typearea");
var doc = pre.ownerDocument.defaultView;
var sel = doc.getSelection();
var range = sel.getRangeAt(0);
var tabNode = document.createTextNode(" ");
range.insertNode(tabNode);
range.setStartAfter(tabNode);
range.setEndAfter(tabNode);
sel.removeAllRanges();
sel.addRange(range);
}
document
.querySelector('button')
.addEventListener('click', putTab);
#typearea {
overflow-x: hidden;
margin: 8px;
max-height: auto;
white-space: pre;
display: block;
width: auto;
line-height: 1.5;
}
<button>Insert Tab</button>
<pre id="typearea" contenteditable>
Some predefined text.
</pre>
希望我把问题说清楚了,谢谢
由于 OP 提供了使可编辑内容至少水平滚动的样式,因此内容在向其附加额外字符时需要再次滚动到其父视图中。
因此,OP 可以使用 content-editable 容器的 scrollTo
方法。但话又说回来,OP 必须弄清楚何时(附加内容)和何时不(例如,在光标仍然完全对齐时预先添加或插入内容)来应用此方法。
但是使用容器的scrollBy
方法涵盖任何场景。
function putTab() {
var pre = document.getElementById("typearea");
var doc = pre.ownerDocument.defaultView;
var sel = doc.getSelection();
var range = sel.getRangeAt(0);
const scrollWidthBefore = pre.scrollWidth;
var tabNode = document.createTextNode(" ");
range.insertNode(tabNode);
range.setStartAfter(tabNode);
range.setEndAfter(tabNode);
sel.removeAllRanges();
sel.addRange(range);
pre.scrollBy(pre.scrollWidth - scrollWidthBefore, pre.scrollHeight);
// // perfect approach for appending content
// // but leads to out of view scrolling in
// // all other cases of perfectly visible
// // content like prepending content or
// // inserting it.
//
// pre.scrollTo(
// pre.scrollWidth - parseFloat(window.getComputedStyle(pre).getPropertyValue('width')),
// pre.scrollHeight,
// );
}
document
.querySelector('button')
.addEventListener('click', putTab);
#typearea {
overflow-x: hidden;
margin: 8px;
max-height: auto;
white-space: pre;
display: block;
width: auto;
line-height: 1.5;
}
<button>Insert Tab</button>
<pre id="typearea" contenteditable>Some predefined content.</pre>