`textNode.splitText(pos)` 弄乱了 Safari 中的插入符位置,将其移动到新节点之前。漏洞?
`textNode.splitText(pos)` messes up caret position in Safari, moves it BEFORE the new node. Bug?
在 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>
在 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>