如何使用 contentEditable 获取 iframe 中当前插入符号位置的像素偏移量
我想使用 contentEditable
在 iframe
中定位一个浮动 div
元素,以防用户输入某个组合键(用于自动完成目的)。
我知道如何获得插入符号位置: document.getElementById('elm1_ifr').contentWindow.getSelection().anchorOffset
我可以用它来计算 div 的 left
属性,但我似乎无法弄清楚如何获得顶部
。
我想到的另一种可能性是使用: document.getElementById('elm1_ifr').contentWindow.getSelection().anchorNode.parentNode
并使用 jQuery 获取偏移量,但如果该父级有很长的文本行,我只能提取第一行的顶部位置。
谁能帮我解决这个问题吗?
I would like to position a floating div
element in an iframe
with contentEditable
, in case the user enters a certain key combination (for auto-complete purposes).
I know how to get the caret position:document.getElementById('elm1_ifr').contentWindow.getSelection().anchorOffset
I can use this to calculate the left
property of the div, but I can't seem to figure out how to get the top
.
Another possibility I thought about was using:document.getElementById('elm1_ifr').contentWindow.getSelection().anchorNode.parentNode
And using jQuery to get the offset, but if that parent has a long text line, I would only be able to extract the top position of the first line.
Can anyone help me with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
执行此操作的唯一可靠方法是在插入符处插入一个临时元素(确保其宽度为零),获取其位置并再次将其删除。您还应该将文本节点的两端(如果它是包含插入符号的文本节点)粘在一起,以确保 DOM 与插入节点之前的状态相同。但请注意,执行此操作(或对可编辑内容进行任何其他手动 DOM 操作)会破坏浏览器的内部撤消堆栈。
这样做的原因是仔细阅读 getBoundingClientRect 的规范
Range
的 () 方法表明,getBoundingClientRect()
没有义务为折叠的 Range 返回 Rect。从概念上讲,并非文档中的每个位置都有明确定义的边界矩形。然而,插入符号在屏幕上确实有物理位置,我认为这应该由选择 API 提供,但目前浏览器中没有任何内容可以提供此功能。The only reliable way of doing this is to insert a temporary element at the caret (ensuring that it is zero width), get its position and remove it again. You should also glue the two ends of the text node (if it was a text node that contained the caret) back together to ensure the DOM is as it was before inserting the node. Note, however, that doing this (or any other manual DOM manipulation on the editable content) breaks the browser's internal undo stack.
The reason for this is that careful reading of the spec for the
getBoundingClientRect()
method ofRange
shows thatgetBoundingClientRect()
is not obliged to return a Rect for a collapsed Range. Conceptually, not every position in the document has a well-defined bounding rectangle. The caret, however, does have physical location on the screen which in my opinion should be provided by the Selection API, but currently there is nothing in browsers to provide this.我今天遇到了这个问题。经过一些测试,我得到了这个工作,没有使用临时元素。
在 IE 中,使用 TextRange 对象的 offsetLeft 和 offsetTop 属性很容易解决这个问题。不过,webkit 还需要一些努力。
这是一个测试,你可以看到结果。 http://jsfiddle.net/gliheng/vbucs/12/
I came into this problem today. After some testing, I got this working, without using temorary element.
In IE, it's easy to work it out with offsetLeft and offsetTop property of a TextRange object. Some effort is needed for webkit though.
Here's a test, you can see the result. http://jsfiddle.net/gliheng/vbucs/12/