使用Javascript和可编辑文档创建内容助手(ctrl+space)
Creating a content assistant (ctrl+space) using Javascript and editable document
我在html文档的可编辑区域创建了一个内容助手的运行示例。因此,如果用户按下键盘上的ctrl和空格键,就会出现一个上下文菜单。当前(参见下面的演示),上下文菜单位于y的右侧位置(文本的下方)。但是它并不是沿着x轴移动的(如果文本变长,那么这个方框将被放置在行首)。
你能帮我解决这个问题吗?问候,mythbu
示例代码:
<!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元素的边界矩形(您假设包含用户输入的文本)作为放置建议对象的位置的参考。
首先,你没有考虑到建议对象位置的边框宽度,所以无论文本有多长,你的建议框都留在左边。
然而,这种方法最终会失败,因为如果文本有多行(其中第二行将比第一行短),边界矩形的宽度将等于第一行的长度(或多或少)。因此,建议对象的位置将不正确。
我关于如何修复代码的第一个想法是将一些内联元素附加到文本(beacon,如果你愿意的话),测量它的位置,将其从DOM中删除并使用计算位置来正确设置建议对象。结果几乎成功了。差不多,因为事实证明,不同的浏览器使用不同的方法来处理可内容的行结尾。例如,Firefox会在行尾插入<br _moz_dirty=""/>
,而Chrome则不会。因此,当我试图将beacon元素附加在文本之后时,它被附加在<br/>
之后,再次导致不正确的位置。
解决方案是改变获取我们正在处理的文本节点的方式,并在其nextSibling之前插入beacon。
下面是工作示例http://jsfiddle.net/MmKXS/10/
注1:我已经删除了添加的空<p></p>
元素的iframe的文档,因为在Chrome文本输入的用户没有插入到它,导致另一个问题与定位建议对象。
注2:目前我的解决方案只适用于在文本末尾定位建议对象,而不是光标位置的,因为它将涉及分割textNodes,插入信标,检查其位置并再次合并textNodes。根据用例,你的代码可能会导致较差的性能和/或可能需要改变如何处理定位您的建议对象的整个方法。
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 为effect Composer创建GodRays效果过程
- 从javascript创建一个列表
- onkeyup无法动态创建多个文本区域
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何访问声音管理器2创建的声音对象
- 我已经创建了一个jquery转盘,并使用if条件来运行和停止转盘
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 使用Facebook live API创建实时视频对象时的隐私设置
- 在动态创建的元素上获取对特定选择器的引用
- 如何创建带有插槽的vue js组件预加载程序
- 如何在创建键时引用来自同一对象的键
- 如何创建JSON数组
- 如何创建一个侦听按键组合的事件侦听器(ctrl 和左/右箭头)
- 我正试图创建一个鼠标事件,该鼠标事件允许用户使用“;ctrl”;键和换档键
- 如何创建ctrl按钮超链接
- 想要在其他服务中覆盖创建的angularJS对象,但是在应用程序中按ctrl +f5后它会被重新初始化
- 使用Javascript和可编辑文档创建内容助手(ctrl+space)
- 在GitHub的新问题页面的标题文本框中按Ctrl+Enter或Enter创建确认弹出框的用户脚本
- 用户脚本,用于在提交问题或通过在 GitHub 中按 Ctrl+Enter(内置热键)发布评论时创建确认弹出窗口