Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Javascript和可编辑文档创建内容助手(ctrl+;空格)_Javascript_Contenteditable_Assistant - Fatal编程技术网

使用Javascript和可编辑文档创建内容助手(ctrl+;空格)

使用Javascript和可编辑文档创建内容助手(ctrl+;空格),javascript,contenteditable,assistant,Javascript,Contenteditable,Assistant,我在html文档的可编辑区域创建了一个运行中的内容助手示例。因此,如果用户按ctrl键并在键盘上加空格,就会出现一个上下文菜单。当前(参见下面的演示),上下文菜单位于右侧y位置(文本下方)。但它不会沿着x轴移动(如果文本变长,则框将播种在行的开头) 你能帮我解决这个问题吗 您好, 迈斯布 示例代码: <!doctype html> <html> <head> <meta http-equiv="content-type" content="text/ht

我在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>

试验
变量iframe=null,iwindow=null,iDocument=null;
函数setUpInput(){
iframe=document.createElement('iframe');
setAttribute('id','iframe test');
setAttribute('frameborder',0);
setAttribute('style','width:100%;height:100%;border:实心1px红色;');
document.getElementById(“输入”).appendChild(iframe);
iwindow=iframe.contentWindow;
idocument=iwindow.document;
idocument.open();
i文档。写(“

”); i文档。关闭(); idocument.body.setAttribute('spellcheck',false); idocument.body.setAttribute('style','font-family:Consolas,serif;font-size:0.8em;'); idocument.body.contentEditable=true; iwindow.onkeydown=函数(e){ 如果(e.ctrlKey&&e.keyCode==32){ createSuggestObject(); 返回false; } 如果(e.ctrlKey)返回false; }; iwindow.onkeypress=函数(e){if(e.ctrlKey)返回false;}; } 函数createSuggestObject(){ 建议=新对象(); 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=“示例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=函数(){ setUpInput(); };
您的解决方案的主要问题是使用p元素的边框(假设包含用户输入的文本)作为放置建议对象的参考

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

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

我关于如何修复代码的第一个想法是在文本中添加一些内联元素(如果愿意,可以添加beacon),测量其位置,将其从DOM中删除,并使用计算出的位置来正确设置suggestion对象

结果几乎成功了。几乎是这样,因为事实证明,不同的浏览器使用不同的访问方法。例如,Firefox在行尾插入
,而Chrome则没有。因此,当我试图将我的beacon元素附加在文本之后时,它被附加在

之后,再次导致位置不正确

解决方案是改变获取我们正在处理的文本节点的方式,并在下一次发布之前插入信标

下面是一个工作示例

注1:我已经删除了在iframe文档中添加的空

元素,因为用户输入的in-Chrome文本没有插入其中,这导致了另一个定位建议对象的问题

注2:就目前而言,我的解决方案仅适用于将建议对象定位在文本末尾,而不是光标位置,因为这将涉及拆分文本节点、插入信标、检查其位置以及再次合并文本节点。根据您对该代码的使用情况,可能会导致性能低下和/或需要改变如何定位建议对象的整个方法