带有 removeChild 的 Chrome 跳转插入符号错误

Posted

技术标签:

【中文标题】带有 removeChild 的 Chrome 跳转插入符号错误【英文标题】:Chrome jumping caret bug with removeChild 【发布时间】:2011-12-05 17:50:05 【问题描述】:

有人可以解释一下 Chrome 中的这个问题吗? removeChild() 函数使插入符号跳转到 div 的末尾。有人有解决方法吗?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var caretX = 0

function keypress(event)
    insertAtCaret('<span id="caretpos"></span>');
    var caretpos = document.getElementById('caretpos')
    //caretX = getX(caretpos) //finds the X position of the element
    removeNode(caretpos)
    return(true)


//Functions used:
function insertAtCaret(text,replaceContents) 
    if(!text)return(false);
    if(replaceContents==null)replaceContents=false;
    if(!replaceContents)//collapse selection:
        var sel = document.getSelection()
        sel.collapseToStart()
    
    return(document.execCommand('insertHTML', false, text))
; 
function removeNode(el)
    el.parentNode.removeChild(el);

</script>
</head>

<body contentEditable="true" onkeypress="return(keypress(event))">
<div>Type some content somewhere here   &gt; &lt; and watch what happens in chrome</div>
</body>
</html>

更新: 我实际上是在尝试通过插入一个虚拟元素,找到它的位置然后删除它来获取用户插入符号的像素位置。也就是说,这个问题是 chrome 中的一个基本问题,以这种方式操作 DOM 会导致插入符号跳转到元素的末尾

【问题讨论】:

你真正想做什么? 对不起蒂姆我试图通过插入一个虚拟元素来获取用户插入符号的像素位置,找到它的位置然后删除它。也就是说,这个问题是 chrome 中的一个基本问题,以这种方式操作 DOM 会导致插入符号跳转到元素的末尾 【参考方案1】:

调用document.execCommand('insertHTML') 后插入符号应该发生的确切情况未定义,但我同意 Chrome 的行为没有帮助。您可以通过使用 Range 的 insertNode() 方法添加您的虚拟元素来绕过它:

var sel = window.getSelection();
sel.collapseToStart();
var span = document.createElement("span");
var range = sel.getRangeAt(0);
range.insertNode(span);

// Get the position here...

span.parentNode.removeChild(span);

整个事情的另一种方法是在支持它的浏览器中使用 Range 的 getBoundingClientRect() 方法。在这里查看我的答案:

Coordinates of selected text in browser page

最后,我一直在为我的Rangy 库编写一个模块来执行此操作。它还没有完成,但这里有一个演示:http://rangy.googlecode.com/svn/trunk/demos/position.html

【讨论】:

这太甜了!非常感谢蒂姆。 Rangy看起来也很棒!我正在使用您在此处详述的 createElement 方法重写我的 insertAtCaret 函数。您能告诉我如何在插入新节点之前删除选定的文本吗? 您的意思是从文档中删除选定的文本吗? sel.deleteFromDocument() 如果是这样。顺便说一句,如果您需要支持 IE Range 或 Selection 是的。我无法让 deleteFromDocument() 工作:collabedit.com/4phyt。我做错了吗? @cronoklee: replaceContents 未定义,因此sel.deleteFromDocument() 永远不会运行。 糟糕——是的,刚刚发现了 setTimeout 代码中的错字!非常感谢蒂姆的帮助 - 非常有用的东西我一定会再次使用。

以上是关于带有 removeChild 的 Chrome 跳转插入符号错误的主要内容,如果未能解决你的问题,请参考以下文章

调用 removeChild(el) 时是不是删除了 el.onclick? [复制]

foreach 中的 DomDocument removeChild 重新索引 dom

Chrome和Firefox溢出:隐藏的跳跃元素

JS学习之DOM节点操作2

在chrome下打开网页出现如下错误,请问怎么解决?

删除节点removeChild()