gpt4 book ai didi

javascript - 使用 Javascript 和可编辑文档创建内容助手 (ctrl+space)

转载 作者:行者123 更新时间:2023-12-02 12:45:31 25 4
gpt4 key购买 nike

我在 html 文档的可编辑区域中创建了内容助手的运行示例。因此,如果用户按下键盘上的 ctrl 和空格键,则会出现上下文菜单。目前(参见下面的演示)上下文菜单位于右侧 y 位置(文本下方)。但它不沿着 x 轴(如果文本变长,框将播种在行的开头)。

你能帮我解决这个问题吗?

您好,神话布

示例代码:

<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Test</title>
<script type="text/javascript">

var iframe = null, iwindow = null, iDocument = null;

function setUpInput() {
iframe = document.createElement( 'iframe' );
iframe.setAttribute( 'id', 'iframe-test' );
iframe.setAttribute( 'frameborder', 0 );
iframe.setAttribute( 'style', 'width:100%; height:100%;border: solid 1px red;' );

document.getElementById( "input" ).appendChild( iframe );

iwindow = iframe.contentWindow;
idocument = iwindow.document;

idocument.open();
idocument.write("<p></p>");
idocument.close();

idocument.body.setAttribute( 'spellcheck', false );
idocument.body.setAttribute( 'style', 'font-family: Consolas,serif;font-size: 0.8em;' );
idocument.body.contentEditable = true;

iwindow.onkeydown = function(e) {
if (e.ctrlKey && e.keyCode == 32) {
createSuggestObject();
return false;
}
if (e.ctrlKey) return false;
};

iwindow.onkeypress = function(e) {if (e.ctrlKey) return false;};
}

function createSuggestObject() {
suggest = new Object();
suggest.box = document.createElement( 'div' );
suggest.box.style.position = 'absolute';
suggest.box.style.width = '120px';
suggest.box.style.overflow = 'auto';
suggest.box.style.border = '1px solid #BEC7E4';
suggest.box.style.display = 'block';
suggest.box.style.marginTop = '16px';
suggest.box.innerHTML = "Example 1";
document.body.appendChild( suggest.box )

var position = iframe.getBoundingClientRect();

var selObj = iwindow.getSelection();
var selRange = selObj.getRangeAt(0);
var p2 = selObj.anchorNode.parentNode.getBoundingClientRect();

suggest.box.style.top = Math.round( window.scrollY + position.top + p2.top) + 'px';
suggest.box.style.left = Math.round( window.scrollX + position.left + p2.left) + 'px';

}

window.onload = function() {
setUpInput();
};
</script>

</head>
<body>
<div id="input"></div>
</body>
</html>

最佳答案

您的解决方案的主要问题是您使用 p 元素的边界矩形(您假设它包含用户输入的文本)作为放置建议对象的位置的引用。

首先,您没有将边界矩形宽度考虑到建议对象的位置,因此无论文本有多长,您的建议框都位于左侧。

但是,这种方法最终会失败,因为如果文本有多于一行(其中第二行比第一行短),则边界矩形的宽度将等于第一行的长度(或多或少) )。因此,建议对象的位置将不正确。

我关于如何修复代码的第一个想法是将一些内联元素附加到文本(信标,如果你愿意的话),测量它的位置,将其从 DOM 中删除并使用计算出的位置正确设置建议对象。

结果几乎成功了。几乎,因为事实证明,不同的浏览器使用 dealing with contentEditable line endings 的不同方法。例如,Firefox 插入 <br _moz_dirty=""/>位于行尾,而 Chrome 则没有。因此,当我尝试在文本后面附加我的 beacon 元素时,它会附加在 <br/> 之后。再次导致位置错误。

解决方案是更改获取我们正在处理的文本节点的方式,并在其 nextSibling 之前插入信标

这是工作示例 http://jsfiddle.net/MmKXS/10/

注释 1:我已删除添加空 <p></p>元素添加到 iframe 文档中,因为在 Chrome 中,用户输入的文本未插入其中,导致定位建议对象时出现另一个问题。

注 2:目前我的解决方案仅适用于将建议对象定位在文本末尾,不适用于光标位置,因为它涉及拆分文本节点、插入信标、检查其位置并再次合并文本节点。根据该代码的用例,可能会导致性能不佳和/或可能需要更改处理建议对象定位的整个方法。

关于javascript - 使用 Javascript 和可编辑文档创建内容助手 (ctrl+space),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8029920/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com