javascript - `textNode.splitText(pos)` 在 Safari 中弄乱了插入符号的位置,将其移动到新节点之前。漏洞?
问题描述
在 Safari 中使用拆分文本节点(在键入时).splitText()
时,插入符号会在新创建的节点之前移动 - 在 Chrome 和 Firefox 中,它按预期保持其在行尾的位置。
我想知道,我是否遇到过错误,什么是干净的解决方法?
function wrapWorld({target}) {
const node = target.childNodes[0];
const pos = node.nodeValue.indexOf('world');
console.log(pos);
if (pos > 0) {
//watch the caret in Safari jump before "world" when split :(
const newNode = node.splitText(pos);
}
}
#editor {
width: 300px;
height: 130px;
border: 1px solid #ccc;
}
<p>Type "hello world" in Safari, watch the caret jump before "world" when it gets split</p>
<div id="editor"
contenteditable="true"
oninput="wrapWorld(event)">
</div>
解决方案
我不能确定这是否真的是一个错误,我没有在规范中进行广泛的搜索以了解这里应该发生什么(内容可编辑通常是规范不足的......),但这两种行为听起来对我来说很合乎逻辑,就像我希望光标在刚刚删除内容时返回一样。
现在,您实际上可以强制 Chrome 和 Firefox 的行为,无论如何这可能是一个好主意。
为此,请使用Selection API了解光标当前的位置,然后在进行拆分后,将其设置为新位置,您可以使用拆分索引进行计算。
function wrapWorld( { target } ) {
const sel = getSelection(); // get current selection
const range = sel.getRangeAt( 0 ); // extract active Range
const node = range.endContainer; // we should be collapsed, so startContainer === endContainer
const cursor_pos = range.endOffset; // the position of our cursor in the whole node
const txt_pos = node.nodeValue.indexOf( 'world' );
if ( txt_pos > -1 ) {
const new_node = node.splitText( txt_pos );
const new_pos = cursor_pos - txt_pos;
if( new_pos > -1 ) {
range.setStart( new_node, new_pos ); // update our range
sel.removeAllRanges();
sel.addRange( range ); // update the Selection
}
}
}
#editor {
width: 300px;
height: 130px;
border: 1px solid #ccc;
}
<p>Type "hello world" in Safari, watch the caret stay where it belongs</p>
<div id="editor"
contenteditable="true"
oninput="wrapWorld(event)">
</div>
推荐阅读
- javascript - 使用 html css 和 js 划分的汉堡包下拉菜单
- sql - 计算客户余额的最佳方法是什么?
- swift - 有没有更好的方法来处理 Sprite Kit 中的结果逻辑?(迅速)
- angular - Angular 5+ 无法保存结果形式的可观察响应
- java - Windows 与 linux 上的另一个 Mysql 数据库编码字符
- javascript - 9 个字符的正则表达式,其中 8 必须是数字
- python - 来自 SQL 模型的 Qt 自定义多选 QComboBox
- angular - 使用 http 时,在订阅之外未定义变量
- dns - 如何使它在我键入 test.com 时从 b.test.com 打开文件?
- html - 如何使用 CSS 只选择前三个元素